text:
199rec.co.uk
24-7recruitment.net
2kpeople.co.uk
365rec.com
3aaa.co.uk
aatomrecruitment.com
abrs.com
absoluteitrecruitment.com
adgold.co.uk
adlib-recruitment.co.uk
agendarecruitment.co.uk
amicusjobs.co.uk
andiamo-group.com
applauseit.co.uk
arcamresources.com
argyllscott.com
arm.co.uk
arrowsgroup.com
artemissearch.com
asginternational.co.uk
auburn-rose.com
avantirec.com
axica-recruitment.com
beaumont-it.co.uk
beprofound.co
bitwave-resource.co.uk
blueglue.co.uk
blueoctopus.co.uk
bmsperformance.com
bodhisearch.com
boldrecruitment.co.uk
brightred.com
capita.co.uk
capitolinternational.com
catservices.co
centena.co.uk
certusrecruitment.com
chassamrecruitment.co.uk
chromarecruitment.com
circlerecruitment.com
cititec.com
compfutures.com
computerfutures.com
computerpeople.co.uk
computerworldpersonnel.co.uk
consolpartners.com
continuoussolutions.co
contractrecruit.co.uk
costelloandreyes.com
cpsgroupuk.com
creativepersonnel.co.uk
criticalpathsolutions.co.uk
ctprecruitment.co.uk
cybercoders.com
darwinrecruitment.com
datascope.co.uk
digitalgurus.co.uk
digitalsourcinggroup.com
district4.io
doyouknowbonobo.co.uk
e-recruiter.co.uk
edison-hill.co.uk
ejspecialists.com
emponics.com
energizerec.com
engagewithus.com
enterit.co.uk
epeoplerecruitment.com
eq50.com
esynergy-solutions.co.uk
eurobase.com
evolution-contract.co.uk
evolutionjobs.co.uk
evosearch.co.uk
experis.co.uk
exploreltd.com
explorerec.com
firstachieve.com
fishtank.cc
flair4recruitment.co.uk
fluidrecruitment.co.uk
forsythbarnes.com
fusionrecruitmentsolutions.com
g2recruitment.com
gcsltd.com
gcsrecruitment.com
ges-it.com.pl
gettechforce.com
giantrecruiting.com
globalresourcingsolutions.co.uk
gopartnership.com
gregoryjamesresourcing.com
greywood.co.uk
gurucareers.com
hackajob.co
hamilton-fraser.co.uk
hanoverit.co.uk
hanrec.com
harpermay.com
haybrook.co.uk
hays-uk.com
hays.com
heatrecruitment.co.uk
hendersonscott.com
hermansearch.com
honorsearch.co.uk
howard-finley.co.uk
hudson.com
huntressgroup.com
huxley.com
hydrogengroup.com
hyphen.com
icredodigital.com
initi8recruitment.com
insight-rec.com
intapeople.com
intelletec.com
investigo.co.uk
involvedsolutions.com
ioassociates.co.uk
iprofile.org
isluk.co.uk
it-talent.co.uk
itecco.co.uk
itssrecruitment.co.uk
jambo.co
jambodigital.co
james-chase.com
jamrecruitment.co.uk
jandnet-recruitment.co.uk
jcomresources.co.uk
jeffersonfrank.com
jitr.co.uk
jjnmedia.com
jonothanbosworth.co.uk
jp-jobs.com
JustIT.co.uk
knowit.co.uk
korusgroup.co.uk
lafosse.com
langleyjames.co.uk
langleyjames.com
langleyjames.net
lavsun.com
lawrenceharvey.com
libertyresourcing.co.uk
loveworklife.com
lynxrecruitment.co.uk
macleanmoore.com
madisonts.com
majorplayers.co.uk
markhadfield.co.uk
markitplacements.co.uk
markloucas.co.uk
maxrec.co.uk
mayflowerltd.com
maylamont.com
metamorphic.co.uk
methods.co.uk
michaelpage.com
mint-rs.com
modis.co.uk
monarchit.co.uk
montaguolsen.com
mortimerspinks.com
mustardjobs.co.uk
newgentechnology.co.uk
next-ventures.com
nicollcurtin.com
novate-it.co.uk
oakleafpartnership.com
oho.co.uk
oliverbernard.co.uk
onboardrecruitment.com
optimum-digital.com
optimussearch.com
opusrs.com
opusrs.com.au
orbis-resourcing.com
oscar-associates.com
oscar-tech.com
osrecruit.com
pagepersonnel.co.uk
parkerwhiteconsulting.com
payettegroup.com
pcrdigital.com
pearsonfrank.com
peoplesource.co.uk
platform-recruitment.com
plexusrs.com
preferred-choice.co.uk
premier-media.co.uk
premiergroupuk.com
premierituk.com
premiermediauk.com
prism-digital.com
pro-quest.co.uk
profectusrecruitment.co.uk
profilescreative.com
prosper-is.com
puredevelopers.co.uk
purple-consultancy.com
qarea.com
radleyjames.com
randstad.co.uk
realit.com
recann.uk
recruitmentgenius.com
redrockconsulting.co.uk
redsevenuk.com
revolutiontechnology.co.uk
ringhamhunter.com
roc-search.com
rutherfordgrant.com
sandersonplc.com
search.co.uk
searchability.co.uk
senitor.com
serendipityrecruitment.com
simplifiedrecruitment.com
skillfindergroup.com
socialheads.co.uk
sourcecoders.io
sourced.ai
southern-lights.co.uk
spherelondon.co.uk
spiergroup.com
spring.com
sqcp.com
stonorsearch.com
stottandmay.com
strategicpeople.co.uk
suite900.com
talentavenue.com
talentedge.co.uk
talentinternational.co.uk
talentsourceglobal.co.uk
talktoneon.com
technet-it.co.uk
technicaltalent.co.uk
technology-leaders.com
tmsilver.com
transition-partners.co.uk
triarecruitment.com
trsgroup.co.uk
unifyndgroup.com
unitingambition.com
vemployee.com
venngroup.com
venturi-group.com
vertechgroup.co.uk
vertex-solutions.co.uk
vsynergize.com
wahoo-recruitment.com
wbrs.com
weareadam.com
weareavion.com
web-cruit.com
webhiring.co.uk
webpointresources.com
welovesalt.com
wesourcetalent.com
x4group.co.uk
x4technology.co.uk
xactplacements.co.uk
xcedesolutions.com
xist4.com
yolkrecruitment.com
yourrecruit.com
yourrecruitit.com

repo_name: jasoncartwright/recruiterdomains

repo_language: JavaScript

mime_type: text/plain


text:
# Recruiter Domains

List of domain names of known recruitment consultants. Suitable to be imported into email server blacklists. Pull requests welcome!

Domain are in https://github.com/jasoncartwright/recruiterdomains/blob/master/domains.txt or https://raw.githubusercontent.com/jasoncartwright/recruiterdomains/master/domains.txt for automatic importing to your mail server.

[![Build Status](https://travis-ci.org/jasoncartwright/recruiterdomains.svg?branch=master)](https://travis-ci.org/jasoncartwright/recruiterdomains)


text:
let vows = require('vows');
let assert = require('assert');
let fs = require('fs');
let path = require('path');
let domainList = path.join(__dirname, '..', 'domains.txt');

vows.describe('Order of the recruiter list').addBatch({
  'is': {
    topic: () => {
      let contents = fs.readFileSync(domainList).toString().split('\n');
      let domains = [];
      contents.forEach((item, index) => {
        if (item !== '') {
          // We use lowercase so sorting works properly
          domains.push(item.toLowerCase());
        }
      });
      return domains;
    },

    'unique': (topic) => {
      let uniqueDomains = Array.from(new Set(topic));
      assert.deepEqual(topic, uniqueDomains);
    },

    'alphabetical': (topic) => {
      let sorted = Array.from(topic).sort();
      assert.deepEqual(topic, sorted);
    }
  }
}).export(module);


text:
--requirement requirements-test.txt
ipython

repo_name: cisagov/join-cisagov

repo_language: Shell


text:
# Welcome #

We're so glad you're thinking about contributing to this open source
project!  If you're unsure or afraid of anything, just ask or submit
the issue or pull request anyway.  The worst that can happen is that
you'll be politely asked to change something.  We appreciate any sort
of contribution, and don't want a wall of rules to get in the way of
that.

Before contributing, we encourage you to read our CONTRIBUTING policy
(you are here), our [LICENSE](LICENSE), and our [README](README.md),
all of which should be in this repository.

## Issues ##

If you want to report a bug or request a new feature, the most direct
method is to [create an
issue](https://github.com/cisagov/join-cisagov/issues) in this
repository.  We recommend that you first search through existing
issues (both open and closed) to check if your particular issue has
already been reported.  If it has then you might want to add a comment
to the existing issue.  If it hasn't then feel free to create a new
one.

## Pull requests ##

If you choose to [submit a pull
request](https://github.com/cisagov/join-cisagov/pulls), you will
notice that our continuous integration (CI) system runs a fairly
extensive set of linters and syntax checkers.  Your pull request may
fail these checks, and that's OK.  If you want you can stop there and
wait for us to make the necessary corrections to ensure your code
passes the CI checks.

If you want to make the changes yourself, or if you want to become a
regular contributor, then you will want to set up
[pre-commit](https://pre-commit.com/) on your local machine.  Once you
do that, the CI checks will run locally before you even write your
commit message.  This speeds up your development cycle considerably.

### Setting up pre-commit ###

There are a few ways to do this, but we prefer to use
[`pyenv`](https://github.com/pyenv/pyenv) and
[`pyenv-virtualenv`](https://github.com/pyenv/pyenv-virtualenv) to
create and manage a Python virtual environment specific to this
project.

If you already have `pyenv` and `pyenv-virtualenv` configured you can
take advantage of the `setup-env` tool in this repo to automate the
entire environment configuration process.

```console
./setup-env
```

Otherwise, follow the steps below to manually configure your
environment.

#### Installing and using `pyenv` and `pyenv-virtualenv` ####

On the Mac, we recommend installing [brew](https://brew.sh/).  Then
installation is as simple as `brew install pyenv pyenv-virtualenv` and
adding this to your profile:

```bash
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

For Linux, Windows Subsystem for Linux (WSL), or on the Mac (if you
don't want to use `brew`) you can use
[pyenv/pyenv-installer](https://github.com/pyenv/pyenv-installer) to
install the necessary tools. Before running this ensure that you have
installed the prerequisites for your platform according to the
[`pyenv` wiki
page](https://github.com/pyenv/pyenv/wiki/common-build-problems).

On WSL you should treat your platform as whatever Linux distribution
you've chosen to install.

Once you have installed `pyenv` you will need to add the following
lines to your `.bash_profile` (or `.profile`):

```bash
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
```

and then add the following lines to your `.bashrc`:

```bash
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

If you want more information about setting up `pyenv` once installed, please run

```console
pyenv init
```

and

```console
pyenv virtualenv-init
```

for the current configuration instructions.

If you are using a shell other than `bash` you should follow the
instructions that the `pyenv-installer` script outputs.

You will need to reload your shell for these changes to take effect so
you can begin to use `pyenv`.

For a list of Python versions that are already installed and ready to
use with `pyenv`, use the command `pyenv versions`.  To see a list of
the Python versions available to be installed and used with `pyenv`
use the command `pyenv install --list`.  You can read more
[here](https://github.com/pyenv/pyenv/blob/master/COMMANDS.md) about
the many things that `pyenv` can do.  See
[here](https://github.com/pyenv/pyenv-virtualenv#usage) for the
additional capabilities that pyenv-virtualenv adds to the `pyenv`
command.

#### Creating the Python virtual environment ####

Once `pyenv` and `pyenv-virtualenv` are installed on your system, you
can create and configure the Python virtual environment with these
commands:

```console
cd join-cisagov
pyenv virtualenv <python_version_to_use> join-cisagov
pyenv local join-cisagov
pip install --requirement requirements-dev.txt
```

#### Installing the pre-commit hook ####

Now setting up pre-commit is as simple as:

```console
pre-commit install
```

At this point the pre-commit checks will run against any files that
you attempt to commit.  If you want to run the checks against the
entire repo, just execute `pre-commit run --all-files`.

## Public domain ##

This project is in the public domain within the United States, and
copyright and related rights in the work worldwide are waived through
the [CC0 1.0 Universal public domain
dedication](https://creativecommons.org/publicdomain/zero/1.0/).

All contributions to this project will be released under the CC0
dedication. By submitting a pull request, you are agreeing to comply
with this waiver of copyright interest.


text:
--requirement requirements.txt
pre-commit


text:
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -o pipefail

USAGE=$(
  cat << 'END_OF_LINE'
Configure a development environment for this repository.

It does the following:
  - Verifies pyenv and pyenv-virtualenv are installed.
  - Creates a Python virtual environment.
  - Configures the activation of the virtual enviroment for the repo directory.
  - Installs the requirements needed for development.
  - Installs git pre-commit hooks.
  - Configures git upstream remote "lineage" repositories.

Usage:
  setup-env [options] [virt_env_name]
  setup-env (-h | --help)

Options:
  -f --force          Delete virtual enviroment if it already exists.
  -h --help           Show this message.
  -i --install-hooks  Install hook environments for all environments in the
                      pre-commit config file.

END_OF_LINE
)

# Flag to force deletion and creation of virtual environment
FORCE=0

# Positional parameters
PARAMS=""

# Parse command line arguments
while (("$#")); do
  case "$1" in
    -f | --force)
      FORCE=1
      shift
      ;;
    -h | --help)
      echo "${USAGE}"
      exit 0
      ;;
    -i | --install-hooks)
      INSTALL_HOOKS=1
      shift
      ;;
    -*) # unsupported flags
      echo "Error: Unsupported flag $1" >&2
      exit 1
      ;;
    *) # preserve positional arguments
      PARAMS="$PARAMS $1"
      shift
      ;;
  esac
done

# set positional arguments in their proper place
eval set -- "$PARAMS"

# Check to see if pyenv is installed
if [ -z "$(command -v pyenv)" ] || { [ -z "$(command -v pyenv-virtualenv)" ] && [ ! -f "$(pyenv root)/plugins/pyenv-virtualenv/bin/pyenv-virtualenv" ]; }; then
  echo "pyenv and pyenv-virtualenv are required."
  if [[ "$OSTYPE" == "darwin"* ]]; then
    cat << 'END_OF_LINE'

  On the Mac, we recommend installing brew, https://brew.sh/.  Then installation
  is as simple as `brew install pyenv pyenv-virtualenv` and adding this to your
  profile:

  eval "$(pyenv init -)"
  eval "$(pyenv virtualenv-init -)"

END_OF_LINE

  fi
  cat << 'END_OF_LINE'
  For Linux, Windows Subsystem for Linux (WSL), or on the Mac (if you don't want
  to use "brew") you can use https://github.com/pyenv/pyenv-installer to install
  the necessary tools. Before running this ensure that you have installed the
  prerequisites for your platform according to the pyenv wiki page,
  https://github.com/pyenv/pyenv/wiki/common-build-problems.

  On WSL you should treat your platform as whatever Linux distribution you've
  chosen to install.

  Once you have installed "pyenv" you will need to add the following lines to
  your ".bashrc":

  export PATH="$PATH:$HOME/.pyenv/bin"
  eval "$(pyenv init -)"
  eval "$(pyenv virtualenv-init -)"
END_OF_LINE
  exit 1
fi

set +o nounset
# Determine the virtual environment name
if [ "$1" ]; then
  # Use the user-provided environment name
  env_name=$1
else
  # Set the environment name to the last part of the working directory.
  env_name=${PWD##*/}
fi
set -o nounset

# Remove any lingering local configuration.
if [ $FORCE -ne 0 ]; then
  rm -f .python-version
  pyenv virtualenv-delete --force "${env_name}" || true
elif [[ -f .python-version ]]; then
  cat << 'END_OF_LINE'
  An existing .python-version file was found.  Either remove this file yourself
  or re-run with --force option to have it deleted along with the associated
  virtual environment.

  rm .python-version

END_OF_LINE
  exit 1
fi

# Create a new virtual environment for this project
if ! pyenv virtualenv "${env_name}"; then
  cat << END_OF_LINE
  An existing virtual environment named $env_name was found.  Either delete this
  environment yourself or re-run with --force option to have it deleted.

  pyenv virtualenv-delete ${env_name}

END_OF_LINE
  exit 1
fi

# Set the local application-specific Python version(s) by writing the
# version name to a file named `.python-version'.
pyenv local "${env_name}"

# Upgrade pip and friends
python3 -m pip install --upgrade pip setuptools wheel

# Find a requirements file (if possible) and install
for req_file in "requirements-dev.txt" "requirements-test.txt" "requirements.txt"; do
  if [[ -f $req_file ]]; then
    pip install --requirement $req_file
    break
  fi
done

# Install git pre-commit hooks now or later.
pre-commit install ${INSTALL_HOOKS:+"--install-hooks"}

# Setup git remotes from lineage configuration
# This could fail if the remotes are already setup, but that is ok.
set +o errexit

eval "$(
  python3 << 'END_OF_LINE'
from pathlib import Path
import yaml
import sys

LINEAGE_CONFIG = Path(".github/lineage.yml")

if not LINEAGE_CONFIG.exists():
    print("No lineage configuration found.", file=sys.stderr)
    sys.exit(0)

with LINEAGE_CONFIG.open("r") as f:
    lineage = yaml.safe_load(stream=f)

if lineage["version"] == "1":
    for parent_name, v in lineage["lineage"].items():
        remote_url = v["remote-url"]
        print(f"git remote add {parent_name} {remote_url};")
        print(f"git remote set-url --push {parent_name} no_push;")
else:
    print(f'Unsupported lineage version: {lineage["version"]}', file=sys.stderr)
END_OF_LINE
)"

# Qapla'
echo "Success!"


text:
setuptools
wheel


text:
# CISA is Hiring #

[![GitHub Build Status](https://github.com/cisagov/join-cisagov/workflows/build/badge.svg)](https://github.com/cisagov/join-cisagov/actions)

Looking for an opportunity to make a difference while leveraging your software
development, product management, procurement, design, content, cloud migration,
outreach, or operations skills? We’re looking for candidates passionate about
our mission to lead the national effort to understand and manage cyber and
physical risk to our critical infrastructure.

Every day, the men and women of CISA work with our partners across the country
to strengthen the backbone of our national and economic security. Often we’re
behind the scenes making sure that the systems and networks Americans rely on
are there when they need them. We work collaboratively with state and local
government, private industry, law enforcement, and top-tier researchers. Join
the team that is proud to protect!

CISA recognizes the value of its workforce and offers a variety of benefits:

- Flexible work schedules, telework, remote work, and both casual and
  professional work environments
- Annual leave, sick leave, and paid federal holidays
- Comprehensive benefit options, including medical, dental, vision, life and
  long-term care insurance, flexible spending accounts, and thrift savings plans
- Access to Employee Assistance Program (EAP)
- SmartBenefits® — a transit benefits subsidy
- Education and development opportunities such as mentoring programs, leadership
  programs, and sponsored graduate degree programs

## Current postings (by team) ##

### Vulnerability Management software engineering team ###

A small shop with a big heart. ❤ We're looking for both junior and senior
developers to help design the tools and systems used by CISA's Vulnerability
Management sub-division.  These are the folks that perform many of our
[cybersecurity assessments](https://www.cisa.gov/cyber-resource-hub).

Our development team is responsible for a majority of the repositories in the
[cisagov organization](https://github.com/cisagov). Take a look around to get a
sense of what we're currently working on.  Recently we've been making a big
push to cloudify all the things, resulting in our new
[COOL](https://github.com/cisagov/cool-system) system. You'll find a good deal
of Python, infrastructure as code (Terraform, Ansible, Packer), and old-school
shell scripting.

We're big fans of [open development in
government](https://digital.gov/communities/open-source/) and promote it
whenever we can.

We appreciate that software development can be an art as much as a science.  Bob
Ross got to pick his own brushes, and so can you!  There are very few
restrictions on what you can craft as your development environment. (But you may
get razzed if registry keys are involved.)

If have any questions for our team, please feel free to join the conversation
over in the [Guild of
Developers](https://github.com/cisagov/development-guide/discussions).

If you are interested in a posting, please send your résumé to: [mark.feldhousen@cisa.dhs.gov](mailto:mark.feldhousen@cisa.dhs.gov)

Adventure awaits!  Huzzah! 🤺

Our current postings:

- 🌟 [Software Engineers](postings/vm_software_engineer.md)

## Even more CISA careers ##

Not a software engineer?  Take a look at the other careers CISA has available:
[https://www.cisa.gov/careers](https://www.cisa.gov/careers)

## Contributing ##

We welcome contributions!  Please see [`CONTRIBUTING.md`](CONTRIBUTING.md) for
details.

## License ##

This project is in the worldwide [public domain](LICENSE).

This project is in the public domain within the United States, and
copyright and related rights in the work worldwide are waived through
the [CC0 1.0 Universal public domain
dedication](https://creativecommons.org/publicdomain/zero/1.0/).

All contributions to this project will be released under the CC0
dedication. By submitting a pull request, you are agreeing to comply
with this waiver of copyright interest.


text:
---
lineage:
  skeleton:
    remote-url: https://github.com/cisagov/skeleton-generic.git
version: '1'


text:
---
# Rather than breaking up descriptions into multiline strings we disable that
# specific rule in yamllint for this file.
# yamllint disable rule:line-length
- color: "eb6420"
  description: This issue or pull request is awaiting the outcome of another issue or pull request
  name: blocked
- color: "000000"
  description: This issue or pull request involves changes to existing functionality
  name: breaking change
- color: "d73a4a"
  description: This issue or pull request addresses broken functionality
  name: bug
- color: "07648d"
  description: This issue will be advertised on code.gov's Open Tasks page (https://code.gov/open-tasks)
  name: code.gov
- color: "0366d6"
  description: Pull requests that update a dependency file
  name: dependencies
- color: "5319e7"
  description: This issue or pull request improves or adds to documentation
  name: documentation
- color: "cfd3d7"
  description: This issue or pull request already exists or is covered in another issue or pull request
  name: duplicate
- color: "b005bc"
  description: A high-level objective issue encompassing multiple issues instead of a specific unit of work
  name: epic
- color: "000000"
  description: Pull requests that update GitHub Actions code
  name: github-actions
- color: "0e8a16"
  description: This issue or pull request is well-defined and good for newcomers
  name: good first issue
- color: "ff7518"
  description: Pull request that should count toward Hacktoberfest participation
  name: hacktoberfest-accepted
- color: "a2eeef"
  description: This issue or pull request will add or improve functionality, maintainability, or ease of use
  name: improvement
- color: "fef2c0"
  description: This issue or pull request is not applicable, incorrect, or obsolete
  name: invalid
- color: "ce099a"
  description: This pull request is ready to merge during the next Lineage Kraken release
  name: kraken 🐙
- color: "a4fc5d"
  description: This issue or pull request requires further information
  name: need info
- color: "fcdb45"
  description: This pull request is awaiting an action or decision to move forward
  name: on hold
- color: "ef476c"
  description: This issue is a request for information or needs discussion
  name: question
- color: "d73a4a"
  description: This issue or pull request addresses a security issue
  name: security
- color: "00008b"
  description: This issue or pull request adds or otherwise modifies test code
  name: test
- color: "1d76db"
  description: This issue or pull request pulls in upstream updates
  name: upstream update
- color: "d4c5f9"
  description: This issue or pull request increments the version number
  name: version bump
- color: "ffffff"
  description: This issue will not be incorporated
  name: wontfix


text:
# Each line is a file pattern followed by one or more owners.

# These owners will be the default owners for everything in the
# repo. Unless a later match takes precedence, these owners will be
# requested for review when someone opens a pull request.
* @dav3r @felddy @jasonodoom @jsf9k @mcdonnnj

# These folks own any files in the .github directory at the root of
# the repository and any of its subdirectories.
/.github/ @dav3r @felddy @jasonodoom @jsf9k @mcdonnnj


text:
---

# Any ignore directives should be uncommented in downstream projects to disable
# Dependabot updates for the given dependency. Downstream projects will get
# these updates when the pull request(s) in the appropriate skeleton are merged
# and Lineage processes these changes.

version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    ignore:
      # Managed by cisagov/skeleton-generic
      - dependency-name: actions/cache
      - dependency-name: actions/checkout
      - dependency-name: actions/setup-go
      - dependency-name: actions/setup-python
      - dependency-name: hashicorp/setup-terraform
      - dependency-name: mxschmitt/action-tmate

  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "weekly"

  - package-ecosystem: "terraform"
    directory: "/"
    schedule:
      interval: "weekly"


text:
---
name: build

on:
  push:
  pull_request:
  repository_dispatch:
    types: [apb]

env:
  CURL_CACHE_DIR: ~/.cache/curl
  PIP_CACHE_DIR: ~/.cache/pip
  PRE_COMMIT_CACHE_DIR: ~/.cache/pre-commit
  RUN_TMATE: ${{ secrets.RUN_TMATE }}

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - id: setup-env
        uses: cisagov/setup-env-github-action@develop
      - uses: actions/checkout@v3
      - id: setup-python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"
      # We need the Go version and Go cache location for the actions/cache step,
      # so the Go installation must happen before that.
      - id: setup-go
        uses: actions/setup-go@v4
        with:
          # There is no expectation for actual Go code so we disable caching as
          # it relies on the existence of a go.sum file.
          cache: false
          go-version: "1.20"
      - name: Lookup Go cache directory
        id: go-cache
        run: |
          echo "dir=$(go env GOCACHE)" >> $GITHUB_OUTPUT
      - uses: actions/cache@v3
        env:
          BASE_CACHE_KEY: "${{ github.job }}-${{ runner.os }}-\
            py${{ steps.setup-python.outputs.python-version }}-\
            go${{ steps.setup-go.outputs.go-version }}-\
            packer${{ steps.setup-env.outputs.packer-version }}-\
            tf${{ steps.setup-env.outputs.terraform-version }}-"
        with:
          # Note that the .terraform directory IS NOT included in the
          # cache because if we were caching, then we would need to use
          # the `-upgrade=true` option. This option blindly pulls down the
          # latest modules and providers instead of checking to see if an
          # update is required. That behavior defeats the benefits of caching.
          # so there is no point in doing it for the .terraform directory.
          path: |
            ${{ env.PIP_CACHE_DIR }}
            ${{ env.PRE_COMMIT_CACHE_DIR }}
            ${{ env.CURL_CACHE_DIR }}
            ${{ steps.go-cache.outputs.dir }}
          key: "${{ env.BASE_CACHE_KEY }}\
            ${{ hashFiles('**/requirements-test.txt') }}-\
            ${{ hashFiles('**/requirements.txt') }}-\
            ${{ hashFiles('**/.pre-commit-config.yaml') }}"
          restore-keys: |
            ${{ env.BASE_CACHE_KEY }}
      - name: Setup curl cache
        run: mkdir -p ${{ env.CURL_CACHE_DIR }}
      - name: Install Packer
        env:
          PACKER_VERSION: ${{ steps.setup-env.outputs.packer-version }}
        run: |
          PACKER_ZIP="packer_${PACKER_VERSION}_linux_amd64.zip"
          curl --output ${{ env.CURL_CACHE_DIR }}/"${PACKER_ZIP}" \
            --time-cond ${{ env.CURL_CACHE_DIR }}/"${PACKER_ZIP}" \
            --location \
            "https://releases.hashicorp.com/packer/${PACKER_VERSION}/${PACKER_ZIP}"
          sudo unzip -d /opt/packer \
            ${{ env.CURL_CACHE_DIR }}/"${PACKER_ZIP}"
          sudo mv /usr/local/bin/packer /usr/local/bin/packer-default
          sudo ln -s /opt/packer/packer /usr/local/bin/packer
      - uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: ${{ steps.setup-env.outputs.terraform-version }}
      - name: Install shfmt
        env:
          PACKAGE_URL: mvdan.cc/sh/v3/cmd/shfmt
          PACKAGE_VERSION: ${{ steps.setup-env.outputs.shfmt-version }}
        run: go install ${PACKAGE_URL}@${PACKAGE_VERSION}
      - name: Install Terraform-docs
        env:
          PACKAGE_URL: github.com/terraform-docs/terraform-docs
          PACKAGE_VERSION: ${{ steps.setup-env.outputs.terraform-docs-version }}
        run: go install ${PACKAGE_URL}@${PACKAGE_VERSION}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip setuptools wheel
          pip install --upgrade --requirement requirements-test.txt
      - name: Set up pre-commit hook environments
        run: pre-commit install-hooks
      - name: Run pre-commit on all files
        run: pre-commit run --all-files
      - name: Setup tmate debug session
        uses: mxschmitt/action-tmate@v3
        if: env.RUN_TMATE


text:
---
name: sync-labels

on:
  push:
    paths:
      - '.github/labels.yml'
      - '.github/workflows/sync-labels.yml'

permissions:
  contents: read

jobs:
  labeler:
    permissions:
      # actions/checkout needs this to fetch code
      contents: read
      # crazy-max/ghaction-github-labeler needs this to manage repository labels
      issues: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Sync repository labels
        if: success()
        uses: crazy-max/ghaction-github-labeler@v4
        with:
          # This is a hideous ternary equivalent so we only do a dry run unless
          # this workflow is triggered by the develop branch.
          dry-run: ${{ github.ref_name == 'develop' && 'false' || 'true' }}


text:
# Software Engineer - Vulnerability Management #

## Major Duties ##

**Secure Software Developer / Validator**:  Analyzes user needs and develops secure
software solutions. Develops, creates, and writes/codes new (or modifies
existing) computer applications, software, or specialized utility programs.
Ensures secure coding practices are implemented during development and provides
patches and upgrades to existing systems. Ensures coding is free of known coding
flaws and weak design approaches, and checks software to identify and remediate
flaws. Recognizes security vulnerabilities in programs while under time,
quality, or cost pressures/constraints. Addresses means to reduce exploitable
software weaknesses and improve capabilities to routinely develop, acquire, and
deploy resilient software products. Enables software security automation and
measurement capabilities through use of common indexing and reporting
capabilities for malware, exploitable software weaknesses, vulnerabilities,
structured threat information, cyber observables, and common attacks which
target software; enhances software transparency and security diagnostic and
measurement capabilities.

**Systems Administrator**:  Installs, configures, troubleshoots, and maintains
server configurations (hardware and software) to ensure their confidentiality,
integrity, and availability. Responsible for access control, passwords, account
creation and administration. Develops and documents systems administration
standard operating procedures; resolves hardware/software interface and
interoperability problems. Ensures systems availability, functionality,
integrity, and efficiency; maintains systems configuration; manages the
installation and integration of system fixes, updates, and enhancements. Also
manages accounts, firewalls, and patches.

## Specific Tasks ##

The tasks that the incumbent will perform as part of their job duties include:

**NCWF Code: 621 Category**: Work in this category includes performing OPM GDS
Cybersecurity Category / Specialty Area: Software Developer [SP-DEV-001] tasks,
as defined by the NIST SP 800-181 National Cyberskills Workforce Framework
(NCWF).  Develops, creates, maintains, and writes/codes new (or modifies
existing) computer applications, software, or specialized utility programs.  The
following specific tasks are performed 40 percent of the time:

- Analyze user needs and software requirements to determine feasibility of
  design within time and cost constraints [T0011]
- Compile and write documentation of program development and subsequent
  revisions, inserting comments in the coded instructions so others can
  understand the program [T0026]
- Conduct trial runs of programs and software applications to ensure that the
  desired information is produced and instructions and security levels are
  correct [T0436]
- Apply cybersecurity functions (e.g., encryption, access control, and identity
  management) to reduce exploitation opportunities [T0553]

**NCWF Code: 451 Category**:  Work in this category includes performing OPM GDS
Cybersecurity Category / Specialty Area: System Administrator [OM-ADM-001]
tasks, as defined by the NIST SP 800-181 National Cyberskills Workforce
Framework (NCWF).  Responsible for setting up and maintaining a system or
specific components of a system (e.g. for example, installing, configuring, and
updating hardware and software; establishing and managing user accounts;
overseeing or conducting backup and recovery tasks; implementing operational and
technical security controls; and adhering to organizational security policies
and procedures).  The following specific tasks are performed 35 percent of the
time:

- Design group policies and access control lists to ensure compatibility with
  organizational standards, business rules, and needs [T0054]
- Provide ongoing optimization and problem-solving support [T0207]
- Install, update, and troubleshoot systems/servers [T0418]
- Manage system/server resources including performance, capacity, availability,
  serviceability, and recoverability [T0498]
- Monitor and maintain system/server configuration [T0501]

**NCWF Code: 141 Category**:  Work in this category includes performing OPM GDS
Cybersecurity Category / Specialty Area: Threat/Warning Analyst [AN-TWA-001]
tasks, as defined by the NIST SP 800-181 National Cyberskills Workforce
Framework (NCWF).  Develops cyber indicators to maintain awareness of the status
of the highly dynamic operating environment. Collects, processes, analyzes, and
disseminates cyber threat/warning assessments.  The following specific tasks are
performed 25 percent of the time:

- Answer requests for information [T0569]
- Provide subject matter expertise to the development of cyber operations
  specific indicators [T0585]
- Conduct in-depth research and analysis [T0615]
- Produce timely, fused, all-source cyber operations intelligence and/or
  indications and warnings intelligence products (e.g., threat assessments,
  briefings, intelligence studies, country studies) [T0758]
- Provide subject-matter expertise and support to planning/developmental forums
  and working groups as appropriate [T0761]
- Provide current intelligence support to critical internal/external
  stakeholders as appropriate [T0783]
- Provide information and assessments for the purposes of informing leadership
  and customers; developing and refining objectives; supporting operation
  planning and execution; and assessing the effects of operations [T0786]
- Work closely with planners, intelligence analysts, and collection managers to
  ensure intelligence requirements and collection plans are accurate and
  up-to-date [T0834]

## Knowledge Required ##

Work comparable to this level involves a mastery of and skill in applying one or
more of the following knowledge areas:

1. total infrastructure protection environments;
1. systems security certification and accreditation requirements and processes; and/or
1. federal information systems security protocols.

The aforementioned knowledge is used in order to:

1. integrate information systems security with other security disciplines;
1. certify systems or network accreditation; and/or
1. ensure coordination and or collaboration on security
activities.

### Specific KSAs ###

Specific knowledge, skills, and abilities required by the incumbent to
successfully fulfill the Major Duties and perform the Tasks required for this
position include:

- Knowledge of secure coding techniques [K0140]
- Knowledge of computer networking concepts and protocols, and network security
  methodologies [K0001]
- Knowledge of the application firewall concepts and functions (e.g., Single
  point of authentication/audit/policy enforcement, message scanning for
  malicious content, data anonymization for PCI and PII compliance, data loss
  protection scanning, accelerated cryptographic operations, SSL security,
  REST/JSON processing) [K0202]
- Knowledge of network protocols such as TCP/IP, Dynamic Host Configuration,
  Domain Name System (DNS), and directory services [K0332]
- Skill in developing applications that can log and handle errors, exceptions,
  and application faults and logging [S0149]
- Ability to develop secure software according to secure software deployment
  methodologies, tools, and practices [A0047]
- Knowledge of operations security [K0499]
- Knowledge of the common networking and routing protocols (e.g. TCP/IP),
  services (e.g., web, mail, DNS), and how they interact to provide network
  communications. [K0565]
- Knowledge of virtualization products (VMware, Virtual PC). [K0610]
- Skill in developing or recommending analytic approaches or solutions to
  problems and situations for which information is incomplete or for which no
  precedent exists. [S0211]
- Skill in evaluating information for reliability, validity, and relevance.
  [S0218]
- Ability to develop or recommend analytic approaches or solutions to problems
  and situations for which information is incomplete or for which no precedent
  exists. [S0080]
- Knowledge of virtualization technologies and virtual machine development and
  maintenance [K0130]
- Knowledge of principles and methods for integrating system components [K0346]

### Specific Tools and Technologies ###

Proficiency with the following tools and technologies are required by the
incumbent to successfully fulfill the Major Duties and perform the Tasks
required for this position include:

- Linux, and similar POSIX operating systems
- Python, and related tooling
- Shell scripting
- Regular expressions
- Docker, or similar containerization tools
- Ansible, or similar IT automation tool
- Terraform, or similar infrastructure as code tool
- Packer, or similar machine image automation tool
- Amazon Web Services (AWS), or similar cloud technologies
- Git version control system
- GitHub workflow
- Agile software development
- Continuous integration and deployment tools

## Other Requirements ##

### CyberSkills Codes ###

This position has been awarded the following OPM GDS (aka NIST NICE Framework)
CyberSkill codes:

- PRIMARY: 621 Software Developer
- SECONDARY: 451 System Administrator
- SECONDARY(alt): 141 Threat/Warning Analyst

[A0047]: https://niccs.cisa.gov/workforce-development/nice-framework/abilities/A0047
[AN-TWA-001]: https://niccs.cisa.gov/workforce-development/nice-framework/work-roles/threatwarning-analyst
[K0001]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0001
[K0130]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0130
[K0140]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0140
[K0202]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0202
[K0332]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0332
[K0346]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0346
[K0499]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0499
[K0565]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0565
[K0610]: https://niccs.cisa.gov/workforce-development/nice-framework/knowledges/K0610
[OM-ADM-001]: https://niccs.cisa.gov/workforce-development/nice-framework/work-roles/system-administrator
[S0080]: https://niccs.cisa.gov/workforce-development/nice-framework/skills/S0080
[S0149]: https://niccs.cisa.gov/workforce-development/nice-framework/skills/S0149
[S0211]: https://niccs.cisa.gov/workforce-development/nice-framework/skills/S0211
[S0218]: https://niccs.cisa.gov/workforce-development/nice-framework/skills/S0218
[SP-DEV-001]: https://niccs.cisa.gov/workforce-development/nice-framework/work-roles/software-developer
[T0011]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0011
[T0026]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0026
[T0054]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0054
[T0207]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0207
[T0418]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0418
[T0436]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0436
[T0498]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0498
[T0501]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0501
[T0553]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0553
[T0569]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0569
[T0585]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0585
[T0615]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0615
[T0758]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0758
[T0761]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0761
[T0783]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0783
[T0786]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0786
[T0834]: https://niccs.cisa.gov/workforce-development/nice-framework/tasks/T0834


text:
# Contribution Guidelines

Please ensure your pull request adheres to the following:

* Search previous suggestions before making a new one to ensure yours is not a duplicate.
* Make an individual pull request for each suggestion.
* Use the following format: \[NAME\]\(LINK\) - DESCRIPTION.
* Keep descriptions simple.
* New categories, or improvements to the existing ones are welcome.
* End all descriptions with a period.
* Make sure your text editor is set to remove trailing whitespace.
* Try to ensure your pull requests only have one commit if possible. You can squash your commits into one before submitting.
* Make your pull request titles and descriptions as detailed as possible. Explain why an asset or resources deserves to be added to the list.
* Make sure your additions are in alphabetical order. This includes the headers and items themselves.
* Ensure that assets you submit are of high quality, documented well, and are recently maintained. It also helps if they're popular so I can research them before adding them to the list.
* This is not meant to be used as a list to advertise your own assets. Free or open-source assets should be prioritized over paid assets if they are of similar quality and feature sets.

Thanks!


text:
CC0 1.0 Universal

Statement of Purpose

The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").

Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.

For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.

1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:

  i. the right to reproduce, adapt, distribute, perform, display, communicate,
  and translate a Work;

  ii. moral rights retained by the original author(s) and/or performer(s);

  iii. publicity and privacy rights pertaining to a person's image or likeness
  depicted in a Work;

  iv. rights protecting against unfair competition in regards to a Work,
  subject to the limitations in paragraph 4(a), below;

  v. rights protecting the extraction, dissemination, use and reuse of data in
  a Work;

  vi. database rights (such as those arising under Directive 96/9/EC of the
  European Parliament and of the Council of 11 March 1996 on the legal
  protection of databases, and under any national implementation thereof,
  including any amended or successor version of such directive); and

  vii. other similar, equivalent or corresponding rights throughout the world
  based on applicable law or treaty, and any national implementations thereof.

2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.

3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.

4. Limitations and Disclaimers.

  a. No trademark or patent rights held by Affirmer are waived, abandoned,
  surrendered, licensed or otherwise affected by this document.

  b. Affirmer offers the Work as-is and makes no representations or warranties
  of any kind concerning the Work, express, implied, statutory or otherwise,
  including without limitation warranties of title, merchantability, fitness
  for a particular purpose, non infringement, or the absence of latent or
  other defects, accuracy, or the present or absence of errors, whether or not
  discoverable, all to the greatest extent permissible under applicable law.

  c. Affirmer disclaims responsibility for clearing rights of other persons
  that may apply to the Work or any use thereof, including without limitation
  any person's Copyright and Related Rights in the Work. Further, Affirmer
  disclaims responsibility for obtaining any necessary consents, permissions
  or other rights required for any use of the Work.

  d. Affirmer understands and acknowledges that Creative Commons is not a
  party to this document and has no duty or obligation with respect to this
  CC0 or use of the Work.

For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>


text:
# Archives of 2018

## Contents
* [Sample Projects](#sample-projects)
* [Tutorials](#tutorials)
* [Libraries & Extensions](#libraries--extensions)
* [Videos](#videos)
* [Articles](#articles)
* [Podcasts](#podcasts)
* [Presentations slides](#presentations-slides)
* [E-Books](#e-books)

## Sample Projects
* [Blangular](https://github.com/danroth27/Blangular) - Blazor + Angular, by Daniel Roth.
* [BlazorAzureSignalRService](https://github.com/danroth27/BlazorAzureSignalRService) - Blazor + Azure SignalR Service.
* [ASP.NET Core Blazor CRUD](https://code.msdn.microsoft.com/vstudio/ASPNET-Core-Blazor-122b108a) - ASP.NET Core Blazor Master/Detail CRUD with Filtering and Sorting using EF.
* [BlazorNasaImages](https://github.com/ncarandini/BlazorNasaImages) - A sample Blazor app that fetches the Nasa Astronomy Picture of the Day.
* [BlazorPong](https://github.com/ctrl-alt-d/blazorpong) - 8 bits pong with blazor and signalR. Warning: Blazor Pong is not finished and is stopped with a knowed SignalR issue with Blazor, more info [here](https://github.com/AdrienTorris/awesome-blazor/pull/19).
* [Demo](https://github.com/blazor-demo/blazor-demo.github.io) - Code of the official demo website.
* [TrendTv](https://github.com/MattMarked/TrendTv) - Fetch video list from YouTube and "zap" in real time between trending videos, filtered by country or category.
* [VocaDB lyrics](https://github.com/riipah/vocadb-lyrics-blazor-proto) - VocaDB lyrics display Blazor proto. [Demo](https://lyrics-proto.vocadb.net/).
* [Blazor.DataDrivenLayout](https://github.com/hutchcodes/Blazor.DataDrivenLayout) - Two example of how to do data driven layouts in Server-side Blazor.
* [BlazorPass](https://github.com/ebekker/BlazorPass) - Blazor UI and ASP.NET Core API to manage Active Directory credentials.
* [Blazor Sushi](https://github.com/lohithgn/blazor-sushi) - Kendo UI Sushi SPA recreated in Blazor.
* [RSS Reader](https://github.com/lohithgn/blazor-rss-reader) - RSS Reader built using Blazor.
* [BlazorGeolocation](https://github.com/EdCharbeneau/BlazorGeolocation) - An example of using Geolocation with Blazor.
* [FMRL](https://github.com/ebekker/FMRL) - Ephemeral Message Service. Messages sent are encrypted, securely transferred, and automatically deleted when they are retrieved.
* [Do](https://github.com/jamie-lord/do) - To Do app.
* [Blazor Contoso University](https://github.com/lohithgn/blazor-contoso-university) - Contoso University in Blazor.
* [Hacker News Clone](https://github.com/lohithgn/blazor-hackernews-clone) - Hacker News Clone. [Demo](http://blazorhackernews.surge.sh/).
* [Randify](https://github.com/tinyioda/Randify) - Spotify Playlist randomizer.
* [Realworld](https://github.com/torhovland/blazor-realworld-example-app) - Blazor realworld example app. [Demo](http://blazor-realworld.azurewebsites.net/).
* [RxBlazor](https://github.com/bmsantos/RxBlazor) - Rx.NET based MessageService demo for Blazor Framework.
* [BlazorChat](https://github.com/danroth27/BlazorChat) - Real-time chat app using ASP.NET Core and Blazor, from Daniel Roth.
* [MatchingGame.Blazor](https://github.com/danroth27/MatchingGame.Blazor) - A sample by Dan Roth.
* [BlazorClipboard](https://github.com/danroth27/BlazorClipboard) - Clipboard API for Blazor.
* [Blazorships](https://github.com/bjorndaniel/Blazorships) - Blazorships, a Blazor implementation of Battleship using SignalR.
* [Calamari Blog](https://github.com/thewebchameleon/calamari-blog-blazor) - A simple blog and portfolio site running on Squidex.
* [Quick CMS](https://github.com/robertsundstrom/quick-cms) - Personal blog engine.
* [Blazume](https://github.com/Amine-Smahi/Blazume) - A simple portfolio/Resume template using Blazor.

## Tutorials
* [Data Driven Layout](https://github.com/hutchcodes/Blazor.DataDrivenLayout) - September 24, 2018 - Two ways of driving the layout based on data in the page.
* [ASP.NET Core Blazor CRUD](https://code.msdn.microsoft.com/vstudio/ASPNET-Core-Blazor-122b108a) - August 20, 2018 - A master/detail HTML CRUD example with sorting and filtering using Entity Framework and Web API.
* [Blazing Chuck](https://davidpine.net/blog/blazing-chuck/) - August 18, 2018 - An example Blazor app that displays random "nerdy" Chuck Norris jokes. [Demo](http://ievangelistblazingchuck.azurewebsites.net/).
* [Blazor + Sitecore](https://visionsincode.wordpress.com/2018/06/30/time-travel-into-the-future-blazor-sitecore-helix/) - June 30, 2018 - Time travel into the future – Blazor + Sitecore + Helix.
* [Blazor Bricks](https://www.codeproject.com/Articles/1241210/WebAssembly-with-Blazor) - May 11, 2018 - A bricks game developed with C# and Blazor.
* [A Nicer Looking Blazor Loading Page](http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/4315/A-Nicer-Looking-Blazor-Loading-Page.aspx) - October 14, 2018 - Customize the Blazor loading page using [SpinKit](https://github.com/tobiasahlin/SpinKit).

## Libraries & Extensions
* [Toastr](https://github.com/BlazorExtensions/Toastr) - A Blazor port of Toastr.js.
* [Trail](https://nuget.org/packages/Trail) - DSL for writing Blazor markup in F# (with an [adapter](https://nuget.org/packages/Trail.BlazorRedux) for working with BlazorRedux).
* [BlazorSplit](https://github.com/BlazorComponents/BlazorSplit) - Resizeable split views ([Demo](https://blazorcomponents.github.io/BlazorSplit/)).
* [Elmah.Io.Blazor](https://github.com/elmahio/Elmah.Io.Blazor) - Logs from Blazor to elmah.io using Microsoft.Extensions.Logging.
* [BlazorOfficeUIFabric](https://github.com/BlazorExtensions/BlazorOfficeUIFabric) - ![GitHub stars](https://img.shields.io/github/stars/BlazorExtensions/BlazorOfficeUIFabric?style=flat-square&cacheSeconds=604800) ![last commit](https://img.shields.io/github/last-commit/BlazorExtensions/BlazorOfficeUIFabric?style=flat-square&cacheSeconds=86400) Microsoft Office Fabric UI port for Blazor.

## Videos
* [What's up with Server Side Blazor?](https://www.youtube.com/watch?v=9QRKjUoA9iY) - December 14, 2018 - ASP.NET Monsters #121: What's up with Server Side Blazor?
* [Razor Components deep dive 1](https://www.youtube.com/watch?v=UzEW0X8a010) - December 5, 2018 - Razor Components deep dive 1, from Edward Charbeneau.
* [Blazor, a New .NET Single Page Application Framework](https://www.youtube.com/watch?v=qrf3OrLHeFI) - November 28, 2018 - Steve Sanderson - Blazor, a New .NET Single Page Application Framework | Øredev 2018.
* [Cascading Parameters in Blazor 0.7.0](https://www.youtube.com/watch?v=J_QZKgBSJBw) - November 24, 2018 - Cascading Parameters in Blazor 0.7.0, by Edward Charbeneau.
* [Blazor File Inputs](https://www.youtube.com/watch?v=-IuZQeZ10Uw) - November 19, 2018 - Blazor File Inputs, by Edward Charbeneau.
* [Visual Studio Toolbox: Blazor Part 2](https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Blazor-Part-2) - November 8, 2018 - Visual Studio Toolbox: Blazor Part 2.
* [Visual Studio Toolbox: Blazor Part 1](https://blogs.msdn.microsoft.com/robertgreen/2018/11/06/visual-studio-toolbox-blazor-part-1/) - November 6, 2018 - Visual Studio Toolbox: Blazor Part 1.
* [The Blazor Show](https://www.youtube.com/watch?v=wwi55L6Qb18&list=PL1rZQsJPBU2StolNg0aqvQswETPcYnNKL&index=0) - October 9, 2018 - ASP.NET Community Standup - The Blazor Show!
* [Developing amazing web apps with ASP.NET Core](https://myignite.techcommunity.microsoft.com/sessions/65901) - September 28, 2018 - Microsoft Ignite 2018: Developing amazing web apps with ASP.NET Core, by Daniel Roth.
* [Blazor StateHasChanged](https://www.twitch.tv/videos/315855936) - September 28, 2018 - Blazor-Fluxor, Bionic and some live demos of building Blazor Component Templates with Blazor 0.6.0.
* [Blazor StateHasChanged](https://www.twitch.tv/videos/313447722) - September 22, 2018 - Blazor 0.6.0 Templates, Razor Components, Hosting with Azure Static Websites, and some live demos using Blazor Interop and Geolocation services.
* [A fistful of Blazor; Its .NET in the browser](https://www.youtube.com/watch?v=5ztMNdCZrRY) - September 21, 2018 - A fistful of Blazor; Its .NET in the browser by William Tulloch at the NDC Sydney.
* [Blazor: Modern Web development with .NET and WebAssembly](https://channel9.msdn.com/Events/dotnetConf/2018/S207) - September 13, 2018 - Blazor: Modern Web development with .NET and WebAssembly during the .NET Conf 2018.
* [What's New in ASP.NET Core?](https://channel9.msdn.com/Events/dotnetConf/2018/S104) - August 11, 2018 - What's New in ASP.NET Core? (31:30).
* [ASP.NET Community Standup - Aug 7, 2018 - Meet the MVC Team!](https://youtu.be/7Eh_l7jEcCo?t=47m35s) - August 7, 2018 - ASP.NET Community Standup - Aug 7, 2018 - Meet the MVC Team!
* [Bionic - Ionic CLI clone for Blazor](https://www.youtube.com/watch?v=_YRR6L2Pzks) - July 8, 2018 - Bionic - Ionic CLI clone for Blazor ([NuGet package](https://www.nuget.org/packages/Bionic)).
* [ASP.NET Community Standup - Meet the Blazor team!](https://www.youtube.com/watch?v=CWuIz9khK-o) - June 12, 2018 - ASP.NET Community Standup - June 12, 2018 - Meet the Blazor team.
* [Blazor, a new .NET SPA framework](https://www.youtube.com/watch?v=JU-6pAxqAa4) - May 7, 2018 - Presentation of Blazor by Steve Sanderson at the NDC Minnesota.
* [.NET Overview & Roadmap](https://channel9.msdn.com/Events/Build/2018/BRK2100) - May 7, 2018 - .NET Overview & Roadmap (at 1:14:00).
* [What's new in Web Development with ASP.NET Core 2.1](https://channel9.msdn.com/Events/Build/2018/BRK2151) - May 6, 2018 - What's new in Web Development with ASP.NET Core 2.1 (Blazor part starts at 1:08:57).
* [Develop ASP.NET Blazor Apps in a Docker Container](https://www.youtube.com/watch?v=jGyFKH5y6LA) - April 26, 2018 - Develop ASP.NET Blazor Apps in a Docker Container, from Coding Blocks.
* [ASP.NET Community Standup - Blazor Update with Dan Roth and Steve Sanderson](https://www.youtube.com/watch?v=_b_fUq5DU0U) - April 3, 2018 - ASP.NET Community Standup - Blazor Update with Dan Roth and Steve Sanderson.
* [WebAssembly and Blazor - .NET Concept of the Week - Episode 9](https://www.youtube.com/watch?v=5HSKDGHijdI) - March 4, 2018 - WebAssembly and Blazor - .NET Concept of the Week - Episode 9.
* [Exploring ASP.NET Blazor](https://www.youtube.com/watch?v=VGotz89_iTY) - Feb 10, 2018 - Exploring ASP.NET Blazor! with Jeffrey T. Fritz.
* [ASP.NET Community Standup](https://www.youtube.com/watch?v=Ta_qXpXQqGQ) - Feb 6, 2018 - ASP.NET Community Standup - Blazor Update.

## Articles
* [Blazor StateHasChanged()](https://edcharbeneau.com/blazor-statehaschanged-113018) - December 14, 2018 - Blazor StateHasChanged().
* [Create Blazor Nuget Package With Azure Devops](https://remibou.github.io/Create-Blazor-Nuget-package-with-Azure-DevOps/) - December 14, 2018 - Create Blazor Nuget Package With Azure Devops.
* [How To Publish A Blazor Component To Nuget Gallery](https://medium.com/swlh/how-to-publish-a-blazor-component-to-nuget-gallery-850d6d1dd37d?WT.mc_id=link-twitter-jeliknes) - December 10, 2018 - How To Publish A Blazor Component To Nuget Gallery.
* [An Ad Hoc Approach to Passing Elements from Blazor to JavaScript](https://visualstudiomagazine.com/blogs/tool-tracker/2018/11/an-ad-hoc-approach.aspx?ajs_uid=5801H8419578J3Z) - December 6, 2018 - An Ad Hoc Approach to Passing Elements from Blazor to JavaScript.
* [Architecting Blazor (and Integrating JavaScript)](https://visualstudiomagazine.com/articles/2018/11/01/architecting-blazor.aspx) - December 4, 2018 - Architecting Blazor (and Integrating JavaScript), from the Visual Studio Magazine.
* [Simple localisation in Blazor](https://chrissainty.com/simple-localisation-in-blazor) - December 3, 2018 - Simple localisation in Blazor.
* [BlazorGrid – A Reusable Grid Component For Blazor](https://ankitsharmablogs.com/blazorgrid-reusable-grid-component-for-blazor/) - December 2, 2018 - BlazorGrid – A Reusable Grid Component For Blazor
* [Visual Studio Code gears up for Blazor](https://visualstudiomagazine.com/articles/2018/11/30/vs-code-blazor.aspx) - November 30, 2018 - Visual Studio Code gears up for Blazor.
* [Validate Request With Recaptcha On A Blazor App And Mediatr](https://remibou.github.io/Validate-request-with-reCaptcha-on-a-Blazor-app-and-MediatR/) - November 24, 2018 - Validate Request With Recaptcha On A Blazor App And Mediatr.
* [Validation Controls using Blazor - Basic Validation Controls](http://www.hishambinateya.com/part1-validation-controls-using-blazor-basic-validation-controls) - November 20, 2018 - Part I: Validation Controls using Blazor - Basic Validation Controls.
* [Blazor StateHasChanged()](https://edcharbeneau.com/blazor-statehaschanged-111618) - November 16, 2018 - Blazor StateHasChanged().
* [Share Blazor Components with Shared Class Libraries](https://daveabrock.com/2018/11/11/using-blazor-shared-libraries/) - November 11, 2018 - Share Blazor Components with Shared Class Libraries.
* [Adding Blazor to existing HTML+JavaScript pages](https://visualstudiomagazine.com/articles/2018/10/01/adding-blazor.aspx) - November 2, 2018 - Adding Blazor to existing HTML+JavaScript pages.
* [Blazor: Working with Events](https://visualstudiomagazine.com/articles/2018/10/01/blazor-event-handling.aspx) - October 31, 2018 - Blazor: Working with Events, by Visual Studio Magazine.
* [Implementing server side CosmosDB pagination in a Blazor Web App](https://chapsas.com/implementing-skiptake-server-side-cosmosdb-pagination-in-a-blazor-web-app/) - October 31, 2018 - Implementing server side CosmosDB pagination in a Blazor Web App (Part 1: Page Number and Page Size).
* [Blazor Q&A with Microsoft's Daniel Roth](https://www.telerik.com/blogs/blazor-qa-with-microsofts-daniel-roth) - October 25, 2018 - Blazor Q&A with Microsoft's Daniel Roth.
* [Building offline Blazor application](https://gunnarpeipman.com/aspnet/offline-blazor-application) - October 24, 2018 - Building offline Blazor application.
* [Service lifetimes in Blazor](https://chrissainty.com/service-lifetimes-in-blazor/) - October 22, 2018 - Service lifetimes in Blazor.
* [Pages in ASP .NET Core: Razor, Blazor and MVC Views](https://wakeupandcode.com/pages-in-asp-net-core-razor-blazor-and-mvc-views/) - October 21, 2018 - Pages in ASP .NET Core: Razor, Blazor and MVC Views.
* [Server-side Blazor applications](https://gunnarpeipman.com/aspnet/server-side-blazor/) - October 19, 2018 - Server-side Blazor applications.
* [Building a blogging app with Blazor: adding authentication](https://chrissainty.com/building-a-blogging-app-with-blazor-adding-authentication/) - October 15, 2018 - Building a blogging app with Blazor: adding authentication.
* [Get Started with Blazor and WebAssembly](https://developer.okta.com/blog/2018/10/15/blazor-and-web-assembly) - October 15, 2018 - Get Started with Blazor and WebAssembly.
* [An overview of Razor Components (server-side Blazor)](http://danpatrascu.com/an-overview-of-razor-components-server-side-blazor/) - October 15, 2018 - An overview of Razor Components (server-side Blazor).
* [A nicer looking Blazor loading page](http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/4315/A-Nicer-Looking-Blazor-Loading-Page.aspx) - October 14, 2018 - A nicer looking Blazor loading page.
* [Deploying a Blazor Application on Azure](https://dzone.com/articles/deploying-a-blazor-application-on-azure) - October 12, 2018 - Deploying a Blazor Application on Azure.
* [A Blazor Tip You Should Almost Certainly Ignore](https://visualstudiomagazine.com/blogs/tool-tracker/2018/10/blazor-tip.aspx) - October 10, 2018 - A Blazor Tip You Should Almost Certainly Ignore.
* [Rendering Medical Images using Blazor and fo-dicom](https://maherjendoubi.io/blazor-dicom/) - October 7, 2018 - Rendering Medical Images using Blazor and fo-dicom.
* [Building Blazor apps with SignalR Core](https://dotnetthoughts.net/building-blazor-apps-with-signalr/) - October 3, 2018 - Building Blazor apps with SignalR Core.
* [Server-Side Blazor to ship in .NET Core 3.0](https://visualstudiomagazine.com/articles/2018/10/03/blazor-update.aspx) - October 3, 2018 - Server-Side Blazor to ship in .NET Core 3.0.
* [Blazor 0.6.0 experimental release now available](https://blogs.msdn.microsoft.com/webdev/2018/10/02/blazor-0-6-0-experimental-release-now-available/) - October 2, 2018 - Blazor 0.6.0 experimental release now available.
* [Integrating JavaScript and C# in the Browser: Beyond the Basics with Blazor](https://visualstudiomagazine.com/articles/2018/09/01/integrating-javascript-csharp.aspx) - October 1, 2018 - Integrating JavaScript and C# in the Browser: Beyond the Basics with Blazor.
* [Cutting Edge - Blazor at Work: Events, Binding and Composition](https://msdn.microsoft.com/magazine/mt830361) - October 1, 2018 - Cutting Edge - Blazor at Work: Events, Binding and Composition.
* [Work with Cassandra API in Cosmos DB](https://www.c-sharpcorner.com/article/blazor-work-with-cassandra-api-in-cosmos-db/) - October 1, 2018 - Work with Cassandra API in Cosmos DB.
* [Blazor - .NET in the browser](https://www.dotnetcurry.com/dotnet/1460/blazor-getting-started) - September 27, 2018 - Blazor - .NET in the browser.
* [Building a blogging app with Blazor: Editing & Deleting Posts](https://chrissainty.com/building-a-blogging-app-with-blazor-editing-deleting-posts/) - September 24, 2018 - Building a blogging app with Blazor: Editing & Deleting Posts.
* [Data Driven Layout in Server-side Blazor](https://hutchcodes.net/2018/09/data-driven-layout-in-razor-components/) - September 24, 2018 - Data Driven Layout in Server-side Blazor.
* [Building a blogging app with Blazor: add post](https://chrissainty.com/building-a-blogging-app-with-blazor-add-post/) - September 18, 2018 - Building a blogging app with Blazor: add post.
* [Dependency Injection Lifetimes in Blazor](https://hutchcodes.net/2018/09/dependency-injection-lifetimes-in-razor-components/) - September 17, 2018 - Dependency Injection Lifetimes in Blazor.
* [How to Consume Web APIs in Blazor](https://visualstudiomagazine.com/articles/2018/09/07/blazor-apis.aspx) - September 13, 2018 - How to Consume Web APIs in Blazor.
* [Integrating Stripe Payment In With Blazor And Aspnet Core](https://remibou.github.io/Integrating-Stripe-payment-in-with-Blazor-and-ASPNET-Core/) - September 11, 2018 - Integrating Stripe Payment In With Blazor And Aspnet Core.
* [Working with the Blazor JavaScript Interop](https://blog.logrocket.com/working-with-the-blazor-javascript-interop-3c2a8d0eb56c) - September 5, 2018 - Working with the Blazor JavaScript Interop.
* [Cutting Edge - Never Mind JavaScript, Here’s Blazor](https://msdn.microsoft.com/magazine/mt829756) - September 4, 2018 - Cutting Edge - Never Mind JavaScript, Here’s Blazor, published on Microsoft Magazine.
* [Web Development - C# in the Browser with Blazor](https://msdn.microsoft.com/fr-fr/magazine/mt829752) - September 4, 2018 - Web Development - C# in the Browser with Blazor, published on Microsoft Magazine.
* [Building a blogging app with Blazor: Listing Posts](https://chrissainty.com/building-a-blogging-app-with-blazor-listing-posts/) - September 3, 2018 - Building a blogging app with Blazor: Listing Posts.
* [Blazor: .NET in the browser](https://dncmagazine.blob.core.windows.net/edition38/DNCMag-Issue38.pdf) - September 1, 2018 - Blazor: .NET in the browser, from DNC Magazine.
* [Integrating Blazor and JavaScript Code](https://visualstudiomagazine.com/articles/2018/08/01/integrating-blazor-javascript.aspx) - August 27, 2018 - Integrating Blazor and JavaScript Code.
* [Building a blogging app with Blazor: Getting Setup](https://chrissainty.com/building-a-blogging-app-with-blazor-getting-setup/) - August 27, 2018 - Building a blogging app with Blazor: Getting Setup.
* [Client side validation with Blazor and System.DataAnnotation](https://remibou.github.io/Client-side-validation-with-Blazor-and-Data-Annotations/) - August 23, 2018 - Client side validation with Blazor and System.DataAnnotation.
* [Writing a Blazor app](https://davidpine.net/blog/blazing-chuck/) - August 20, 2018 - Writing a Blazor app.
* [Localizing DateTime (and numbers) in Blazor](https://remibou.github.io/Localizing-DateTime-in-Blazor/) - August 17, 2018 - Localizing DateTime (and numbers) in Blazor.
* [Introduction to Server-side Blazor aka Razor Components](https://chrissainty.com/introduction-to-server-side-blazor-aka-razor-components/) - August 11, 2018 - Introduction to Server-side Blazor aka Razor Components.
* [I18n With Blazor And Aspnet Core](https://remibou.github.io/I18n-with-Blazor-and-ASPNET-Core/) - August 11, 2018 - Internationalizing a Blazor App with ASPNET Core as backend service.
* [WebAssembly](https://davidpine.net/blog/webassembly-interview/) - August 5, 2018 - Interview with Steve Sanderson (Talking Blazor).
* [Web Assembly and Blazor: Re-assembling the Web](https://weblog.west-wind.com/posts/2018/Jul/31/Web-Assembly-and-Blazor-Reassembling-the-Web) - July 31, 2018 - Web Assembly and Blazor: Re-assembling the Web.
* [Understanding Server-Side Blazor](https://www.c-sharpcorner.com/article/understanding-server-side-blazor/) - July 29, 2018 - Understanding Server-Side Blazor.
* [Blazor 0.5.0 experimental release now available](https://blogs.msdn.microsoft.com/webdev/2018/07/25/blazor-0-5-0-experimental-release-now-available/) - July 25, 2018 - Blazor 0.5.0 experimental release now available.
* [CSRF protection with ASPNET Core and Blazor](https://remibou.github.io/CSRF-protection-with-ASPNET-Core-and-Blazor-Week-29/) - July 22, 2018 - CSRF protection with ASPNET Core and Blazor.
* [Blazor for Knockout.js Developers](https://blog.usejournal.com/blazor-for-knockout-js-developers-bfeefaacffc3) - July 20, 2018 - A brief comparison between two of Steve Sanderson’s Creations.
* [Uploading a file in a Blazor app](https://remibou.github.io/Upload-file-with-Blazor/) - July 12, 2018 - Uploading a file in a Blazor app.
* [Adding search to Blazor applications](https://gunnarpeipman.com/search2/blazor-search/) - July 11, 2018 - Adding search to Blazor applications.
* [SPA framework on .Net via WebAssembly](https://koukia.ca/blazor-spa-framework-on-net-via-webassembly-b7a0046e7f21) - July 10, 2018 - SPA framework on .Net via WebAssembly.
* [ASP.NET Core Blazor CRUD](https://code.msdn.microsoft.com/vstudio/ASPNET-Core-Blazor-122b108a) - July 9, 2018 - ASP.NET Core Blazor Master/Detail CRUD with Filtering and Sorting using EF.
* [Improved Cascading Dropdowns With Blazor](https://www.mikesdotnetting.com/article/320/improved-cascading-dropdowns-with-blazor) - July 5, 2018 - Improved Cascading Dropdowns With Blazor.
* [Hosting a Blazor App in Azure Storage Static Websites](https://anthonychu.ca/post/blazor-azure-storage-static-websites/) - June 28, 2018 - Hosting a Blazor App in Azure Storage Static Websites.
* [Implementing Google OAuth with Blazor](https://remibou.github.io/Google-OAuth-with-Blazor-ASPNET-Core-Week-26/) - June 28, 2018 - Implementing Google OAuth with Blazor (0.4) and ASPNET Core 2.1.1.
* [Web Assembly, Blazor and the future of Web Development](https://medium.com/@ZombieCodeKill/web-assembly-blazor-and-the-future-of-web-development-c240fbe5e5be) - June 25, 208 - Web Assembly, Blazor and the future of Web Development.
* [Hosting Blazor on Netlify](https://mattferderer.com/host-blazor-on-netlify) - Hosting Blazor on Netlify.
* [Who is Blazor for Exactly?](https://wildermuth.com/2018/06/13/Who-is-Blazor-for-Exactly) - June 13, 208 - Who is Blazor for Exactly?
* [Blazor 0.4.0 experimental release now available](https://blogs.msdn.microsoft.com/webdev/2018/06/07/blazor-0-4-0-experimental-release-now-available/) - June 7, 2018 - Blazor 0.4.0 experimental release now available.
* [Blazor Update Boosts .NET/JavaScript Interoperability](https://visualstudiomagazine.com/articles/2018/06/08/blazor-0-4-0.aspx) - June 8, 2018 - Blazor Update Boosts .NET/JavaScript Interoperability.
* [An Introduction to Blazor](https://remibou.github.io/An-Introduction-to-Blazor-Week-22/) - June 5, 2018 - An Introduction to Blazor.
* [Creating an SPA Using Razor Pages With Blazor](https://medium.freecodecamp.org/how-to-create-a-single-page-application-using-razor-pages-with-blazor-9d010fd6be45) - June 4, 2018 - Creating an SPA Using Razor Pages With Blazor ([Article on FreeCodeCamp](https://medium.freecodecamp.org/how-to-create-a-single-page-application-using-razor-pages-with-blazor-9d010fd6be45) - [Article on DZone](https://dzone.com/articles/creating-an-spa-using-razor-pages-with-blazor)).
* [Cascading DropDownList in Blazor Using EF Core](http://ankitsharmablogs.com/cascading-dropdownlist-in-blazor-using-ef-core/) - May 14, 2018 - Creating a cascading dropdown list in Blazor using Entity Framework Core database first approach.
* [Deploying a Blazor Application on IIS](http://ankitsharmablogs.com/deploying-a-blazor-application-on-iis/) - May 14, 2018 - Deploying an ASP.NET Core hosted Blazor application with the help of IIS 10 on a Windows 10 machine.
* [Blazor Steals the Show in VSLive!](https://visualstudiomagazine.com/articles/2018/05/03/vslive-austin.aspx) - May 3, 2018 - Blazor Steals the Show in VSLive! .NET Keynote.
* [Blazor 0.3.0 experimental release now available](https://blogs.msdn.microsoft.com/webdev/2018/05/02/blazor-0-3-0-experimental-release-now-available/) - May 2, 2018 - Blazor 0.3.0 experimental release now available.
* [Blazor, Razor, WebAssembly, and Mono](https://daveaglick.com/posts/blazor-razor-webassembly-and-mono) - April 24, 2018 - Blazor, Razor, WebAssembly, and Mono, How the pieces fit together.
* [BlazeDown with Blazor](http://edcharbeneau.com/blazedown-with-blazor) - April 20, 2018 - BlazeDown with Blazor (Blazor + Markdown = BlazeDown!).
* [Blazor 0.2.0 release now available](https://blogs.msdn.microsoft.com/webdev/2018/04/17/blazor-0-2-0-release-now-available/) - April 18, 2018 - Blazor 0.2.0 release now available.
* [ASP.NET Core – CRUD Using Blazor And Entity Framework Core](http://ankitsharmablogs.com/asp-net-core-crud-using-blazor-and-entity-framework-core/) - April 9, 2018 - Creating a web application using Blazor with the help of Entity Framework Core.
* [Using C# await against JS Promises in Blazor](https://joonasw.net/view/csharp-await-and-js-promises-in-blazor) - April 7, 2018 - Using C# await against JS Promises in Blazor.
* [Create a CRUD App using Blazor and ASP.NET Core](http://www.talkingdotnet.com/create-a-crud-app-using-blazor-and-asp-net-core/) - April 5, 2018 - Create a CRUD App using Blazor and ASP.NET Core.
* [Blazor – You Want To Run .NET Where?!](https://dotnetcore.gaprogman.com/2018/04/05/blazor-you-want-to-run-net-where/) - April 5, 2018 - Blazor – You Want To Run .NET Where?!
* [Blazor introduction](https://maherjendoubi.io/blazor-introduction/) - March 30, 2018 - Blazor introduction.
* [What is Blazor and why is it so exciting?](https://chrissainty.com/what-is-blazor-and-why-is-it-so-exciting/) - March 24, 2018 - What is Blazor and why is it so exciting?
* ['Death to JavaScript!' Blazor, for .NET Web Apps Using WebAssembly, Goes Alpha](https://visualstudiomagazine.com/articles/2018/03/23/blazor-alpha.aspx) - March 23, 2018 - 'Death to JavaScript!' Blazor, for .NET Web Apps Using WebAssembly, Goes Alpha.
* [Get started building .NET web apps that run in the browser with Blazor](https://blogs.msdn.microsoft.com/webdev/2018/03/22/get-started-building-net-web-apps-in-the-browser-with-blazor/) - March 22, 2018 - Get started building .NET web apps that run in the browser with Blazor.
* [Blazor and .NET Core hosting – the future’s bright](http://blog.tdwright.co.uk/2018/03/05/blazor-and-net-core-hosting-the-futures-bright) - March 5, 2018 - Blazor and .NET Core hosting – the future’s bright.
* [Building SPAs with C#](http://danpatrascu.com/building-spas-with-c/) - February 13, 2018 - Building SPAs with C#.
* [Blazor: a web UI framework running C# and .NET in the browser](https://www.oxfordcc.co.uk/blog/blazor-a-web-ui-framework-running-csharp-and-dotnet-in-the-browser) - February 8, 2018 - Blazor: a web UI framework running C# and .NET in the browser.
* [A new experiment: Browser-based web apps with .NET and Blazor](https://blogs.msdn.microsoft.com/webdev/2018/02/06/blazor-experimental-project/) - February 6, 2018 - A new experiment: Browser-based web apps with .NET and Blazor.
* [Blazor: a technical introduction](http://blog.stevensanderson.com/2018/02/06/blazor-intro/) - February 6, 2018 - Blazor: a technical introduction.

## Podcasts
* [SDN Cast #118 - With Rainer Stropek and Serverside Blazor!](https://www.youtube.com/watch?v=S66mK_30gPE) - November 8, 2018 - Weekly SDN Cast with special gues Rainer Stropek talking about and showing off Blazor!
* [Ed Charbeneau on Blazor](https://crosscuttingconcerns.com/Podcast-099-Ed-Charbeneau-Blazor) - September 17, 2018 - Ed Charbeneau on Blazor.
* [Blazor brings .NET to Web Assembly with Steve Sanderson](https://hanselminutes.com/642/blazor-brings-net-to-web-assembly-with-steve-sanderson) - July 26, 2018 - Blazor brings .NET to Web Assembly with Steve Sanderson.
* [Episode 037 – Blazor with Daniel Roth](https://6figuredev.com/podcast/episode-037-blazor-with-daniel-roth/) - April 30, 2018 - Episode 037 – Blazor with Daniel Roth.
* [MS Dev Show : Blazor](https://www.youtube.com/watch?v=xJtpYsVRggE) - March 19, 2018 - MS Dev Show Episode 184: Blazor (.NET in WebAssembly) with Dan Roth & Steve Sanderson.

## Presentations slides
* [WebAssembly and Blazor – the future of frontend development?](https://github.com/kkalinowski/Wasm-Blazor-Presentation) - December 12, 2018 - WebAssembly and Blazor – the future of frontend development?. Slides: [PPTX](https://raw.githubusercontent.com/kkalinowski/Wasm-Blazor-Presentation/master/presentation/Blazor.pptx). Demo's source code: [GitHub](https://github.com/kkalinowski/Wasm-Blazor-Presentation/tree/master/src/BlazorDemo).
* [C# running in the browser via WebAssembly](https://www.infoq.com/presentations/blazor-web-assembly) - December, 2018 - "C# running in the browser via WebAssembly" by Scott Sauber. Slides: [PDF](https://scottsauber.files.wordpress.com/2018/12/blazor.pdf).
* [SPA Revolution with WebAssembly and ASP.NET Blazor](https://javascript-conference.com/javascriptecmascript/spa-revolution-with-webassembly-and-asp-net-blazor/) - October 16, 2018 - "SPA Revolution with WebAssembly and ASP.NET Blazor" session at the International JavaScript Conference. Slides: [PPTX](https://learn-blazor.com/slides/blazor-intro.pptx).
* [Blazor: Modern Web development with .NET and WebAssembly]() - August 11, 2018 - "Blazor: Modern Web development with .NET and WebAssembly" session at the .NET Conf 2018. Video: [Channel 9](https://channel9.msdn.com/Events/dotnetConf/2018/S207). Slides: [PPTX](https://github.com/dotnet-presentations/dotnetconf2018/blob/master/Technical/Decks/Blazor_Modern%20Web%20development%20with%20.NET%20and%20WebAssembly.pptx?raw=true) or [GitHub](https://github.com/dotnet-presentations/dotnetconf2018/blob/master/Technical/Decks/Blazor_Modern%20Web%20development%20with%20.NET%20and%20WebAssembly.pptx).
* [Blazor v1.1](https://www.slideshare.net/elGuerre/blazor-v11) - June 28, 2018 - Blazor v1.1.
* [Blazor - An Introduction](https://www.slideshare.net/JamieTaylor112/blazor-an-introduction) - April 14, 2018 - Blazor, An Introduction.
* [An experimental .NET framework for the browser](https://github.com/bjablonsky/blazor-presentation) - April, 2018 - An experimental .NET framework for the browser. Slides: [PPTX](https://raw.githubusercontent.com/bjablonsky/blazor-presentation/master/Blazor.pptx). Demo's source code: [GitHub](https://github.com/bjablonsky/blazor-presentation/tree/master/src).

## E-Books
* [Dockerizing ASP.NET Core and Blazor Applications on Mac](https://www.c-sharpcorner.com/ebooks/dockerizing-asp-net-core-and-blazor-applications-on-mac) - October 30, 2018 - Dockerizing ASP.NET Core and Blazor Applications on Mac.


text:
# Archives of 2017

## Contents
* [Videos](#videos)
* [Articles](#articles)
* [Podcasts](#podcasts)

## Videos
* [Web Apps can’t really do that, can they? - Steve Sanderson](https://www.youtube.com/watch?v=MiLAE6HMr10&feature=youtu.be&t=31m45s) - July 10, 2017 - Web Apps can’t really do that, can they? - Steve Sanderson.

## Articles
* [Running Blazor on Mono in the browser](http://blog.stevensanderson.com/2017/11/05/blazor-on-mono/) - November 5, 2017 - Running Blazor on Mono in the browser.
* [.NET and WebAssembly - Is this the future of the front-end?](https://www.hanselman.com/blog/NETAndWebAssemblyIsThisTheFutureOfTheFrontend.aspx) - August 12, 2017 - .NET and WebAssembly - Is this the future of the front-end?

## Podcasts
* [.NET Rocks, WebAssembly and Blazor with Steve Sanderson](https://www.dotnetrocks.com/?show=1455) - July 4, 2017 - .NET Rocks 1455, WebAssembly and Blazor with Steve Sanderson.
* [Inside WebAssembly with Mozilla Fellow David Bryant](https://hanselminutes.com/581/inside-webassembly-with-mozilla-fellow-david-bryant) - May 25, 2017 - Inside WebAssembly with Mozilla Fellow David Bryant.


text:
[metadata]
name = kindlestrip
version = 1.37.0
description = Strips the penultimate record from Mobipocket ebooks
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/jefftriplett/kindlestrip
author = Paul Durrant
maintainer = Jeff Triplett
maintainer_email = jeff.triplett@gmail.com
license = Unlicense
license_file = LICENSE
classifiers =
    Development Status :: 5 - Production/Stable
    Environment :: Web Environment
    Intended Audience :: Developers
    License :: Public Domain
    Operating System :: OS Independent
    Programming Language :: Python :: 3
    Programming Language :: Python :: 3 :: Only
    Programming Language :: Python :: 3.7
    Programming Language :: Python :: 3.8
    Programming Language :: Python :: 3.9
    Programming Language :: Python :: 3.10
    Programming Language :: Python :: Implementation :: CPython
    Topic :: Utilities

[options]
packages = find:
py_modules = kindlestrip
python_requires = >=3.7

[options.entry_points]
console_scripts =
    kindlestrip = kindlestrip:main

[bdist_wheel]
universal = 1

repo_name: jefftriplett/kindlestrip

repo_language: Python


text:
@_default:
    just --list

@build:
    python -m build

@bump:
    bumpversion minor

@check:
    twine check dist/*

@pre-commit:
    git ls-files -- . | xargs pre-commit run --config=.pre-commit-config.yaml --files

@test:
    pytest

@upload:
    twine upload dist/*


text:
include AUTHORS.md
include LICENSE
include README.rst

exclude .bumpversion.cfg
exclude requirements.txt
exclude tasks.py

recursive-exclude * __pycache__
recursive-exclude * *.py[co]


text:
build
bumpversion
twine


text:
# Authors

## Primary Author

- Paul Durrant

## Contributors (in order of contribution)

- Kevin Hendricks
- Jeff Triplett <jefftriplett>
- Austin Ziegler <halostatue>


text:
#!/usr/bin/env python
#
# This is a python script. You need a Python interpreter to run it.
# For example, ActiveState Python, which exists for windows.
#
# This script strips the penultimate record from a Mobipocket file.
# This is useful because the current KindleGen add a compressed copy
# of the source files used in this record, making the ebook produced
# about twice as big as it needs to be.
#
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
#
# Written by Paul Durrant, 2010-2011, paul@durrant.co.uk
#
# Changelog
#  1.00 - Initial version
#  1.10 - Added an option to output the stripped data
#  1.20 - Added check for source files section (thanks Piquan)
#  1.30 - Added Support for K8 style mobis
#  1.31 - To get K8 style mobis to work properly, need to replace SRCS section with section of 0 length
#  1.35a- Backport of fixes from 1.32-1.35 to 1.31 to workaround latest Kindlegen changes
#  1.36 - Backport of updates
#  1.37 - Python3 support
from __future__ import annotations

__version__ = "1.37.0"

import sys
import os
import struct

import getopt
import locale
import codecs
import imp

iswindows = sys.platform.startswith("win")

# Because Windows (and Mac OS X) allows full unicode filenames and paths
# any paths in pure bytestring python 2.X code must be utf-8 encoded as they will need to
# be converted on the fly to full unicode for Windows platforms.  Any other 8-bit str
# encoding would lose characters that can not be represented in that encoding
# these are simple support routines to allow use of utf-8 encoded bytestrings as paths in main program
# to be converted on the fly to full unicode as temporary un-named values to prevent
# the potential mixing of unicode and bytestring string values in the main program

def pathof(s):
    if isinstance(s, str):
        print("Warning: pathof expects utf-8 encoded byestring: ", s)
        if iswindows:
            return s
        return s.encode("utf-8")
    if iswindows:
        return s.decode("utf-8")
    return s

# force string to be utf-8 encoded whether unicode or bytestring
def utf8_str(p, enc="utf-8"):
    if isinstance(p, str):
        return p.encode("utf-8")
    if enc != "utf-8":
        return p.decode(enc).encode("utf-8")
    return p

# get sys.argv arguments and encode them into utf-8
def utf8_argv():
    global iswindows
    if iswindows:
        # Versions 2.x of Python don't support Unicode in sys.argv on
        # Windows, with the underlying Windows API instead replacing multi-byte
        # characters with '?'.  So use shell32.GetCommandLineArgvW to get sys.argv
        # as a list of Unicode strings and encode them as utf-8

        from ctypes import POINTER, byref, cdll, c_int, windll
        from ctypes.wintypes import LPCWSTR, LPWSTR

        GetCommandLineW = cdll.kernel32.GetCommandLineW
        GetCommandLineW.argtypes = []
        GetCommandLineW.restype = LPCWSTR

        CommandLineToArgvW = windll.shell32.CommandLineToArgvW
        CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)]
        CommandLineToArgvW.restype = POINTER(LPWSTR)

        cmd = GetCommandLineW()
        argc = c_int(0)
        argv = CommandLineToArgvW(cmd, byref(argc))
        if argc.value > 0:
            # Remove Python executable and commands if present
            start = argc.value - len(sys.argv)
            return [argv[i].encode("utf-8") for i in range(start, argc.value)]
        # this should never happen
        return None
    else:
        argv = []
        argvencoding = sys.stdin.encoding
        if argvencoding == None:
            argvencoding = sys.getfilesystemencoding()
        if argvencoding == None:
            argvencoding = "utf-8"
        for arg in sys.argv:
            if type(arg) == str:
                argv.append(arg.encode("utf-8"))
            else:
                argv.append(arg.decode(argvencoding).encode("utf-8"))
        return argv

# Python 2.X is broken in that it does not recognize CP65001 as UTF-8
def add_cp65001_codec():
    try:
        codecs.lookup("cp65001")
    except LookupError:
        codecs.register(
            lambda name: name == "cp65001" and codecs.lookup("utf-8") or None,
        )
    return

# Almost all sane operating systems now default to utf-8 (or full unicode) as the
# proper default encoding so that all files and path names
# in any language can be properly represented.

def set_utf8_default_encoding():
    if sys.getdefaultencoding() in ["utf-8", "UTF-8", "cp65001", "CP65001"]:
        return

    # Regenerate setdefaultencoding.
    imp.reload(sys)
    sys.setdefaultencoding("utf-8")

    for attr in dir(locale):
        if attr[0:3] != "LC_":
            continue
        aref = getattr(locale, attr)
        try:
            locale.setlocale(aref, "")
        except locale.Error:
            continue
        try:
            lang = locale.getlocale(aref)[0]
        except (TypeError, ValueError):
            continue
        if lang:
            try:
                locale.setlocale(aref, (lang, "UTF-8"))
            except locale.Error:
                os.environ[attr] = lang + ".UTF-8"
    try:
        locale.setlocale(locale.LC_ALL, "")
    except locale.Error:
        pass
    return

class Unbuffered:
    def __init__(self, stream):
        self.stream = stream

    def write(self, data):
        self.stream.write(data)
        self.stream.flush()

    def __getattr__(self, attr):
        return getattr(self.stream, attr)

class StripException(Exception):
    pass

def patchdata(datain, off, new):
    dout = []
    dout.append(datain[:off])
    dout.append(new)
    dout.append(datain[off + len(new) :])
    return b"".join(dout)

def joindata(datain, new):
    dout = []
    dout.append(datain)
    dout.append(new)
    return b"".join(dout)

class SRCSStripper:
    def sec_info(self, secnum):
        start_offset, flgval = struct.unpack_from(
            b">2L",
            self.datain,
            78 + (secnum * 8),
        )
        if secnum == self.num_sections:
            next_offset = len(self.datain)
        else:
            next_offset, nflgval = struct.unpack_from(
                b">2L",
                self.datain,
                78 + ((secnum + 1) * 8),
            )
        return start_offset, flgval, next_offset

    def loadSection(self, secnum):
        start_offset, tval, next_offset = self.sec_info(secnum)
        return self.datain[start_offset:next_offset]

    def __init__(self, datain):
        if datain[0x3C : 0x3C + 8] != b"BOOKMOBI":
            print(datain[0x3C : 0x3C + 8])
            raise StripException("invalid file format")
        self.datain = datain
        (self.num_sections,) = struct.unpack(b">H", datain[76:78])

        # get mobiheader
        mobiheader = self.loadSection(0)

        # get SRCS section number and count
        self.srcs_secnum, self.srcs_cnt = struct.unpack_from(
            b">2L",
            mobiheader,
            0xE0,
        )
        if self.srcs_secnum == 0xFFFFFFFF or self.srcs_cnt == 0:
            raise StripException("File doesn't contain the sources section.")

        print("SRCS section number is: ", self.srcs_secnum)
        print("SRCS section count is: ", self.srcs_cnt)

        # store away srcs sections in case the user wants them later
        self.srcs_headers = []
        self.srcs_data = []
        for i in range(self.srcs_secnum, self.srcs_secnum + self.srcs_cnt):
            data = self.loadSection(i)
            self.srcs_headers.append(data[0:16])
            self.srcs_data.append(data[16:])

        # find its SRCS region starting offset and total length
        self.srcs_offset, fval, temp2 = self.sec_info(self.srcs_secnum)
        next = self.srcs_secnum + self.srcs_cnt
        next_offset, temp1, temp2 = self.sec_info(next)
        self.srcs_length = next_offset - self.srcs_offset
        print("SRCS length is: 0x%x" % self.srcs_length)

        if self.datain[self.srcs_offset : self.srcs_offset + 4] != b"SRCS":
            raise StripException("SRCS section num does not point to SRCS.")

        # first write out the number of sections
        self.data_file = self.datain[:76]
        self.data_file = joindata(
            self.data_file,
            struct.pack(b">H", self.num_sections),
        )

        # we are going to make the SRCS section lengths all  be 0
        # offsets up to and including the first srcs record must not be changed
        last_offset = -1
        for i in range(self.srcs_secnum + 1):
            offset, flgval, temp = self.sec_info(i)
            last_offset = offset
            self.data_file = joindata(
                self.data_file,
                struct.pack(b">L", offset) + struct.pack(b">L", flgval),
            )
            # print "section: %d, offset %0x, flgval %0x" % (i, offset, flgval)

        # for every additional record in SRCS records set start to last_offset (they are all zero length)
        for i in range(self.srcs_secnum + 1, self.srcs_secnum + self.srcs_cnt):
            temp1, flgval, temp2 = self.sec_info(i)
            self.data_file = joindata(
                self.data_file,
                struct.pack(b">L", last_offset) + struct.pack(b">L", flgval),
            )
            # print "section: %d, offset %0x, flgval %0x" % (i, last_offset, flgval)

        # for every record after the SRCS records we must start it earlier by an amount
        # equal to the total length of all of the SRCS section
        delta = 0 - self.srcs_length
        for i in range(self.srcs_secnum + self.srcs_cnt, self.num_sections):
            offset, flgval, temp = self.sec_info(i)
            offset += delta
            self.data_file = joindata(
                self.data_file,
                struct.pack(b">L", offset) + struct.pack(b">L", flgval),
            )
            # print "section: %d, offset %0x, flgval %0x" % (i, offset, flgval)

        # now pad it out to begin right at the first offset
        # typically this is 2 bytes of nulls
        first_offset, flgval = struct.unpack_from(b">2L", self.data_file, 78)
        self.data_file = joindata(
            self.data_file,
            b"\0" * (first_offset - len(self.data_file)),
        )

        # now add on every thing up to the original src_offset and then everything after it
        dout = []
        dout.append(self.data_file)
        dout.append(self.datain[first_offset : self.srcs_offset])
        dout.append(self.datain[self.srcs_offset + self.srcs_length :])
        self.data_file = b"".join(dout)

        # update the srcs_secnum and srcs_cnt in the new mobiheader
        offset0, flgval0 = struct.unpack_from(b"2L", self.data_file, 78)
        offset1, flgval1 = struct.unpack_from(b">2L", self.data_file, 86)
        mobiheader = self.data_file[offset0:offset1]
        mobiheader = (
            mobiheader[:0xE0]
            + struct.pack(b">L", 0xFFFFFFFF)
            + struct.pack(b">L", 0)
            + mobiheader[0xE8:]
        )
        self.data_file = patchdata(self.data_file, offset0, mobiheader)
        print("done")

    def getResult(self):
        return self.data_file

    def getStrippedData(self):
        return self.srcs_data

    def getHeader(self):
        return self.srcs_headers

def usage(progname):
    print(
        f"KindleStrip {__version__}. "
        "Written 2010-2012 by Paul Durrant and Kevin Hendricks.",
    )
    print("Strips the Sources record from Mobipocket ebooks")
    print("For ebooks generated using KindleGen 1.1 and later that add the source")
    print("Usage:")
    print(f"    {progname} [Options] <infile> <outfile>")
    print("Options: ")
    print(" -h  print this help message ")
    print(" -d  dump stripped SRCS records to the current working directory ")

def main(argv=utf8_argv()):
    progname = os.path.basename(argv[0])
    DUMPSRCS = False
    try:
        opts, args = getopt.gnu_getopt(argv[1:], "hd")
    except getopt.GetoptError as err:
        print(str(err))
        usage(progname)
        return 2

    if len(args) != 2:
        usage(progname)
        return 1

    for o, a in opts:
        if o == "-h":
            usage(progname)
            sys.exit(0)
        if o == "-d":
            DUMPSRCS = True

    infile = args[0]
    outfile = args[1]
    try:
        data_file = open(pathof(infile), "rb").read()
        strippedFile = SRCSStripper(data_file)
        open(pathof(outfile), "wb").write(strippedFile.getResult())
        if DUMPSRCS:
            headers = strippedFile.getHeader()
            secdatas = strippedFile.getStrippedData()
            for i in range(0, len(headers)):
                hdr = headers[i]
                secdata = secdatas[i]
                if hdr[0:4] == "SRCS":
                    fname = "kindlestrip_source_archive.zip"
                elif hdr[0:4] == "CMET":
                    fname = "kindlestrip_build_log.txt"
                else:
                    fname = "kindlestrip_unknown%05d.dat" % i
                print("Stripped Record Type: ", hdr[0:4], " file: ", fname)
                fname = "./" + fname
                open(pathof(fname), "wb").write(secdata)

    except StripException as e:
        print("Error: %s" % e)
        return 1
    return 0

if __name__ == "__main__":
    add_cp65001_codec()
    set_utf8_default_encoding()
    sys.exit(main())


text:
from __future__ import annotations

from setuptools import setup

setup()