text:
//digitalClockLog and logDigits functions modified from example sketches included in RTCLib library created by Adafruit.
//All other functions and methods created by 934Virginia, 2019-07-08, and released into the public domain.

#include <time.h>

#include <Dusk2Dawn.h>
#include "Norman.h"

//Outputs a formatted year's worth of data for graphical comparison to real-world data.
//Just copy-paste the content of the serial monitor to a .csv, and you're good to go.

void digitalClockLog(time_t Xtime) {
  // digital clock display of the time
  //Formatted to match NCDC timestamps for climatic normals.

  //logDigits(getYear(Xtime));
  //Serial.print('-');
  logDigits(getMonth(Xtime));
  Serial.print('-');
  logDigits(getDay(Xtime));
  Serial.print("T");
  logDigits(getHour(Xtime));
  Serial.print(':');
  logDigits(getMinute(Xtime));
  Serial.print(':');
  logDigits(getSecond(Xtime));
}

void logDigits(int digits) {
  // utility function for digital clock display: prints preceding colon and leading 0
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

////////////////////////////////////STRUCT INPUT////////////////////////////////////////////////////////////////
//SetTarget_Origin Structure is (Latitude, Longitude, Timezone(standard time), Season Start, Season Length).
//Season Length is unused for Origin parameters.

//SetRangeTDP Structure is (coldest day of year, hottest day of year, Minimum value on coldest day, Maximum value on coldest day, Minimum value on hottest day, Maximum value on hottest day).
//if you can't find minimum and maximum Dew Point values for your location on the hottest and coldest days of the year,
//you'll need to use the RHtoDP(Temp, RH, "F") function for the temperature and RH data at those points in time.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Denver
struct SetTarget_Origin Target = {39.7392, -104.9903, -7, getTime(2010, 1, 1, 0, 0, 0), 365};
struct SetTarget_Origin Origin = {39.7392, -104.9903, -7, getTime(2010, 1, 1, 0, 0, 0), 365};
struct SetRangeTDP Temperature = {getTime(2010, 12, 30, 0, 0, 0), getTime(2010, 7, 10, 0, 0, 0), 24.8, 39.0, 60.8, 85.1};
struct SetRangeTDP DewPoint = {getTime(2010, 12, 30, 0, 0, 0), getTime(2010, 7, 10, 0, 0, 0), 12.9, 16.7, 42.2, 48.6};

time_t currentTime = getTime(2010, 1, 1, 0, 0, 0);

void setup() {
  Serial.begin(9600);
  Serial.print("\"");
  Serial.print("Dateime");
  Serial.print("\",\"");
  Serial.print("Temperature F");
  Serial.print("\",\"");
  Serial.print("Dewpoint F");
  Serial.print("\",\"");
  Serial.print("Percent Relative Humidity");
  Serial.println("\"");

}

void loop() {

  currentTime += 3600;

  /*
  //If you want to print whether or not the sun is up, uncomment this section. This messes up the formatting for comparisons, though.
  time_t testoRise = getSun(currentTime, Target, Origin, "Rise");
  time_t testoSet = getSun(currentTime, Target, Origin, "Set");

  if (currentTime >= testoRise && currentTime < testoSet) {
    Serial.println("DAY");
  }
  else {
    Serial.println("NIGHT");
  }
  */

  //Get your projections
  float testoT = getTDP(currentTime, Target, Origin, Temperature, 150);
  float testoDP = getTDP(currentTime, Target, Origin, DewPoint, 150);
  float testoRH = getRH(testoT, testoDP, "F");
  //float testoRH = getRH(testoT, testoDP, "C");

  //Silly way to ensure it stops printing the values after a year.
  if (getYear(currentTime) == 2010)
  {
    Serial.print("\"");
    digitalClockLog(currentTime);
    Serial.print("\",\"");
    Serial.print(testoT);
    Serial.print("\",\"");
    Serial.print(testoDP);
    Serial.print("\",\"");
    Serial.print(testoRH);
    Serial.println("\"");
  }

}


text:
# About
This project attempts to create a comprehensive list of resources related to sidechain design and development.

## Terminology
According to the original [sidechains whitepaper](https://blockstream.com/sidechains.pdf) by Back et al, a sidechain is:

> a blockchain that validates data from other blockchains (p. 8)

An example of a sidechain under this definition would be Ethereum, a blockchain that can validate data from the bitcoin blockchain in the form of [SPV proofs](https://medium.com/summa-technology/cross-chain-auction-technical-f16710bfe69f).

Back et al go on to define a pegged sidechain as:

> a sidechain whose assets can be imported from and returned to other chains; that is, a sidechain that supports two-way pegged assets. (p.8)

The blockchain that an asset is imported from is the "mainchain" or "parent chain", and the blockchain that the asset is imported to is the sidechain. The mutual portability between a mainchain and a sidechain is referred to as a "two-way peg" due to the way that the value of an asset is "pegged" 1:1 when minted on a sidechain i.e. a pegged asset minted on a sidechain should always be redeemable 1:1 (minus any fees) for the asset it represents on the mainchain.

Thus, crucial to the definition of a pegged sidechain, in the author's humble opinion, is that the portability of assets between a mainchain and sidechain should be permissionless; that is, no permission from any third part(y)(ies) should be required to import an asset into and export an asset from a sidechain. Back et al say as much as well:

> 1. Assets which are moved between sidechains should be able to be moved back by whomever their current holder is, and nobody else (including previous holders).
> 2. Assets should be moved without counterparty risk; that is, there should be no ability for a dishonest party to prevent the transfer occurring. (p. 5)

Taken together, we can say that a pegged sidechain is:

> a blockchain that validates data from other blockchains and supports permissionless, counterparty-free two-way pegged assets.

Based on observations by the author, this is the definition that most people probably think of when they use the term "sidechains", as opposed to the older and simpler definition given by Back et al. And so, while technically what is being referred to here is a "pegged sidechain", the same concept is now colloquially referred to simply as "sidechain" and this is how the term is used in this project as well.

# Papers

- 2014-10-22: [Enabling Blockchain Innovations with Pegged Sidechains](https://blockstream.com/sidechains.pdf)

- 2016-04-01: [Drivechains, Sidechains and Hybrid 2-way peg Designs](https://docs.rsk.co/Drivechains_Sidechains_and_Hybrid_2-way_peg_Designs_R9.pdf)

- 2017-08-21: [Merged Mining: Curse of Cure?](https://eprint.iacr.org/2017/791)

- 2017-09-05: [Driveproof: Sidechain Headers On Mainchain (SHM)](https://zmnscpxj.github.io/sidechain/driveproof/index.html)

- 2017-09-23: [Proof-of-mainstake](https://zmnscpxj.github.io/sidechain/mainstake/index.html)

- 2017-12-02: [Sidechain Weaknesses](https://zmnscpxj.github.io/sidechain/weakness/index.html)

- 2018-06-28: [Research of Merged Mining Technology in Bitcoin Blockchain Scaling](http://www.wcse.org/WCSE_2018/W072.pdf)

- 2018-07-03: [CountAcks Drivechain](https://github.com/rsksmart/bips/blob/master/BIP-R11.md)

- 2018-10-17: [Sidechains: Decoupled Consensus Between Chains](https://www.horizen.io/assets/files/Horizen-Sidechains-Decoupled-Consensus-Between-Chains.pdf)

- 2018-10-30: [Proof-of-Work Sidechains](https://eprint.iacr.org/2018/1048.pdf)

- 2018-12-18: [Proof-of-Stake Sidechains](https://eprint.iacr.org/2018/1239.pdf)

- 2019-01-18: [Proof-of-Stake Bitcoin Sidechains v0.0.1](https://github.com/nomic-io/bitcoin-peg/blob/master/bitcoinPeg.md)

- 2020-01-01: [Zendoo: a zk-SNARK Verifiable Cross-Chain Transfer Protocol Enabling Decoupled and Decentralized Sidechains](https://eprint.iacr.org/2020/123.pdf)

- 2020-11-12: [Horizon: A Gas-Efficient Trustless Bridge for Cross-Chain Transactions](https://harmony.one/crosschain.pdf)

- 2020-12-31: [Softchains: Sidechains as a Soft Fork via Proof-of-Work Fraud Proofs](https://gist.github.com/RubenSomsen/7ecf7f13dc2496aa7eed8815a02f13d1)

# Blog posts

- 2014-10-26: [A simple explanation of Bitcoin "Sidechains"](https://gendal.me/2014/10/26/a-simple-explanation-of-bitcoin-sidechains/)

- 2015-04-10: [Pegged Sidechains Whitepaper Notes](http://kevinriggen.com/Bitcoin/2015-04-10-Pegged-Sidechains-Whitepaper-Notes)

- 2015-11-24: [Drivechain - The Simple Two Way Peg](https://www.truthcoin.info/blog/drivechain/)

- 2017-01-30: [Blind Merged Mining](https://www.truthcoin.info/blog/blind-merged-mining/)

- 2017-03-08: [OP_WITHDRAWPROOFVERIFY — The op code that powers SPV sidechains](https://medium.com/@Chris_Stewart_5/op-withdrawproofverify-the-op-code-that-powers-spv-sidechains-cefce996a324)

- 2018-08-30: [Ion Stage 2: Toward a General Interoperability Protocol (Part 1)](https://medium.com/clearmatics/ion-stage-2-toward-a-general-interoperability-protocol-part-1-d12b9d7316d3)

- 2019-04-17: [Why Drivechain Is Harder to Understand Than Previous Soft Forks](https://www.drivechain.info/blog/hard-to-understand/)

- 2019-04-17: [Is Liquid A "Real" Sidechain? Greg Maxwell Weighs In](https://www.drivechain.info/blog/liquid/)

- 2019-12-10: [Blind Merged Mining with covenants ( sighash_anyprevout / op_ctv )](https://gist.github.com/RubenSomsen/5e4be6d18e5fa526b17d8b34906b16a5)

- 2020-02-09: [Ideas on how to construct sidechains for chains that have covenant capabilities](https://gist.github.com/corollari/0da107093fd21d49cefddab268386cec)

- 2020-04-30: [The difference between XCAT and Drivechain](https://lightco.in/2020/04/30/xcat-drivechain/)

- 2020-08-02: [Comparing two-way bitcoin pegs](https://lightco.in/2020/08/02/bitcoin-pegs/)

- 2020-11-08: [Scaling bitcoin with sidechains](https://lightco.in/2020/11/08/sidechains/)

# Discussion threads

- 2014-04-12: [Why do people think that side-chains are going to be secure?](https://www.reddit.com/r/Bitcoin/comments/22vn4m/why_do_people_think_that_sidechains_are_going_to/)

- 2014-10-23: [Sidechains whitepaper AMA](https://www.reddit.com/r/IAmA/comments/2k3u97/we_are_bitcoin_sidechain_paper_authors_adam_back/)

- 2014-12-20: [The relationship between Proof-of-Publication and Anti-Replay Oracles](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2014-December/007029.html)

- 2016-10-02: [Drivechain proposal using OP_COUNT_ACKS](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-October/013174.html)

- 2017-02-24: [How an anchored Proof of Stake Sidechain can help the Bitcoin main chain](https://www.reddit.com/r/Bitcoin/duplicates/5vy4qc/how_an_anchored_proof_of_stake_sidechain_can_help/)

- 2017-06-10: [Drivechain -- Request for discussion](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-June/014558.html)

- 2017-07-10: [Updating the Scaling Roadmap](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-July/014718.html)

- 2017-09-05: [Sidechain headers on mainchain (unification of drivechains and spv proofs)](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-September/014910.html)

- 2017-09-23: [Sidechains: Mainstake](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-September/015045.html)

- 2017-12-01: [Two Drivechain BIPs](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-December/015339.html)

- 2018-01-17: [NiPoPoW criticism](https://twitter.com/peterktodd/status/953511085008609280)

- 2019-07-04: [SIDECHAINS ARE NOT LAYER 2](https://twitter.com/gakonst/status/1146793685545304064)

- 2020-12-31: [Softchains: Sidechains as a Soft Fork via Proof-of-Work Fraud Proofs](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-December/018331.html)

# Presentations

- 2015-current: [Drivechain presentations](https://www.drivechain.info/literature/index.html)

- 2015-06-28: [SF Bitcoin Devs Seminar: Sidechains: Bringing New Elements to Bitcoin](https://youtu.be/Twynh6xIKUc)

- 2018-10-17: [Horizen Sidechains: Decoupled Consensus Between Chains](https://youtu.be/HzuJ48zyhKU)

- 2019-04-18: [Proof-of-Stake Sidechains for Cardano](https://docs.google.com/presentation/d/17x25AfvnMOpmXFO7wqs5q0AtW4yrYJeVPS2Lb22thyo/edit#slide=id.g5118426647_0_0)

# Interviews

- 2015-08-17: [Sidechains and Lightning Networks with Rusty Russell](https://softwareengineeringdaily.com/2015/08/17/sidechains-and-lightning-networks-with-rusty-russell/)

- 2016-04-19: [Interview with Greg Maxwell: Lightning Network Better Than Sidechains for Scaling Bitcoin](https://bitcoinmagazine.com/articles/greg-maxwell-lightning-network-better-than-sidechains-for-scaling-bitcoin-1461077424)

- 2017-11-15: [Daniel Krawisz and Paul Sztorc talk Drivechain](https://www.youtube.com/watch?v=iMNLB7Q8z80)

- 2018-09-30: [Let's Talk Bitcoin! #377 Sidechains, Drivechains and the Apple Store](https://letstalkbitcoin.com/blog/post/lets-talk-bitcoin-377-sidechains-drivechains-and-the-apple-store)

- 2020-08-27: [Cosmos Unchained: Bitcoin Peggy Showdown](https://www.youtube.com/watch?v=ArSftVH1Ads)

- 2020-09-17: [How Bitcoin Sidechains are the Altcoin Killer! An Interview with Paul Sztorc on Drivechains](https://youtu.be/BbcIAaWScUc)

# News

- 2014-04-16: [Side Chains: The How, The Challenges and the Potential](https://bitcoinmagazine.com/articles/side-chains-challenges-potential)

- 2014-10-23: [Sidechains White Paper Imagines New Future for Digital Currency Development](https://www.coindesk.com/sidechains-white-paper-ecosystem-reboot)

- 2014-10-25: [Bitcoin 2.0: Sidechains And Ethereum And Zerocash, Oh My!](https://techcrunch.com/2014/10/25/bitcoin-2-0-sidechains-and-zerocash-and-ethereum-oh-my/)

- 2017-06-05: [Are Sidechains a Better Solution for Bitcoin’s Scaling Debate?](https://www.coindesk.com/are-sidechains-a-better-solution-for-bitcoins-scaling-debate)

- 2018-01-17: [The Sidechains Breakthrough Almost Everyone in Bitcoin Missed](https://www.coindesk.com/sidechains-breakthrough-almost-everyone-bitcoin-missed)

- 2018-02-19: [Sidechains: Why These Researchers Think They Solved a Key Piece of the Puzzle](https://bitcoinmagazine.com/articles/sidechains-why-these-researchers-think-they-solved-key-piece-puzzle)

- 2018-09-25: [Bitcoin Takes a Step Toward Becoming a ‘Multi-Network’ Cryptocurrency](https://www.coindesk.com/bitcoin-just-took-a-step-toward-becoming-a-multi-network-cryptocurrency)

- 2019-02-27: [It's 2019, Where Are Bitcoin's Sidechains?](https://www.forbes.com/sites/ktorpey/2019/02/27/its-2019-where-are-bitcoins-sidechains/#7d917c553b4f)

- 2020-12-08: [RSK Is Evolving; Powpeg Leverages Hash Power To Switch From Bitcoin To Sidechain And Back](https://bitcoinmagazine.com/articles/rsk-is-evolving-powpeg-leverages-hash-power-to-switch-from-bitcoin-to-sidechain-and-back)

# Patents

- 2018-03-27: [Transferring ledger assets between blockchains via pegged sidechains](https://patents.google.com/patent/US20160330034A1/en)

# Semi-related
While not directly related to sidechains _per se_, the following resources may be useful to understand the design space and tradeoffs around sidechains, and may describe complementary technologies as well.

## Centralized pegs

- 2019-01-24: [Wrapped Tokens: A multi-institutional framework for tokenizing any asset](https://wbtc.network/assets/wrapped-tokens-whitepaper.pdf)

- 2019-07-09: [HTLC and Atomic Peg](https://github.com/bnb-chain/BEPs/blob/master/BEP3.md)

## Collateralized pegs

- 2018-10-15: [Retrofitting a two-way peg between blockchains](https://arxiv.org/pdf/1908.03999.pdf)

- 2019-03-15: [XCLAIM: Trustless, Interoperable, Cryptocurrency-Backed Assets](https://eprint.iacr.org/2018/643.pdf)

- 2019-08-16: [tBTC: A Decentralized Redeemable BTC-backed ERC-20 Token](https://docs.keep.network/tbtc/)

- 2020-05-02: [Zcash Pegzone v2](https://github.com/ZcashFoundation/zcash-pegzone/blob/f8e22c4f9345d71256f98cd5d192e17de4c9b1dc/README.md)

- 2020-10-06: [Decentralized Custody Scheme with Game-Theoretic Security](https://arxiv.org/pdf/2008.10895.pdf)

- 2020-10-08: [Introducing the Wormhole Bridge](https://medium.com/certus-one/introducing-the-wormhole-bridge-24911b7335f7)

- 2021-01-XX: [Axelar Network: Connecting Applications with Blockchain Ecosystems](https://static1.squarespace.com/static/5f7679246f2afb311bbb67dd/t/602d3503ad35b40d1bdc209c/1613575428020/axelar_whitepaper_v1.pdf)

- 2021-01-25: [Introducing StakePeg: A trust-reduced two-way bitcoin peg](https://lightco.in/2021/01/25/stakepeg/)

- 2021-02-25: [How Gravity works](https://blog.althea.net/how-gravity-works/)

- 2022-06-22: [Proof-of-Stake Bitcoin Sidechains v2.1](https://gist.github.com/mappum/da11e37f4e90891642a52621594d03f6)

- 2021-09-13: [Optics is Here](https://medium.com/celoorg/optics-is-here-42aa610675ce)

- 2022-01-XX: [Nomad - a new design for radically cheaper cross-chain communication without header verification](https://docs.nomad.xyz/)

- 2022-04-22: [Bridging Sapling: Private Cross-Chain Transfers](https://arxiv.org/abs/2204.10611)

- 2022-12-14: [sBTC: Design of a Trustless Two-way Peg for Bitcoin](https://stx.is/sbtc-pdf)

## Federated pegs

- 2015-06-08: [Announcing Sidechain Elements: Open source code and developer sidechains for advancing Bitcoin](https://blockstream.com/2015/06/08/en-714/)

- 2017-01-06: [Strong Federations: An Interoperable Blockchain Solution to Centralized Third Party Risks](https://blockstream.com/strong-federations.pdf)

- 2019-01-29: [RSK: Bitcoin Powered Smart Contracts](https://www.rsk.co/Whitepapers/RSK-White-Paper-Updated.pdf)

- 2020-05-22: [Liquid: A Bitcoin Sidechain](https://blockstream.com/assets/downloads/pdf/liquid-whitepaper.pdf)

- 2020-12-02: [Building the Most Secure, Permissionless and Uncensorable Bitcoin Peg](https://medium.com/iovlabs-innovation-stories/building-the-most-secure-permissionless-and-uncensorable-bitcoin-peg-b5dc7020e5ec)

- 2021-01-XX: [Minpeg, a miners' multisig in the peg](https://github.com/rsksmart/RSKIPs/blob/master/IPs/RSKIP198.md)

## One-way pegs

- 2020-01-01: [Permissionless Bitcoin Childchains w/ Continuous Proof of Bitcoin Burn (CPoBB) and 2-way-value-pegs (2wvp)](https://bitcointalk.org/index.php?topic=5214173.0)

- 2020-06-28: [Soft pegged sidechains](https://gist.github.com/fernandonm/cb9f719b125d93fb84e0988917bdde2a)

- 2020-12-12: [Spacechains presentation](https://twitter.com/SomsenRuben/status/1337863852202090505)

## Cross-chain atomic swaps

- 2018-06-23: [COMIT Network: Connect all the Blockchains!!!](https://comit.network/blog/2018/06/23/connect-all-the-blockchains)

- 2018-10-03: [Interledger: How to Interconnect All Blockchains and Value Networks](https://medium.com/xpring/interledger-how-to-interconnect-all-blockchains-and-value-networks-74f432e64543)

- 2018-10-03: [The Missing Tool to Cross-Chain Development and Interoperable Blockchains: the Chain Abstraction Layer](https://medium.com/liquality/the-missing-tool-to-cross-chain-development-2ebfe898efa1)

- 2020-05-11: [Succinct Atomic Swap](https://youtu.be/TlCxpdNScCA)

- 2020-09-02: [Launching OpenDEX - The Decentralized Exchange Standard](https://blog.exchangeunion.com/launching-opendex-the-decentralized-exchange-standard-b907d2a99b5a)

- 2021-01-12: [Vector 0.1.0 Mainnet Release](https://medium.com/connext/vector-0-1-0-mainnet-release-9496ae52c422)

## Miscellaneous

- 2018-07-24: [Proposals to bridge to Ethereum](https://github.com/jpitts/eth-community-discussions/blob/master/proposals-to-bridge.md)

- 2018-10-24: [Niji: Bitcoin Bridge Utilizing Payment Channels](https://arxiv.org/abs/1810.10194)

- 2019-03-22: [Sidechains and interoperability](https://arxiv.org/pdf/1903.04077.pdf)

- 2019-05-21: [Interchain Standards](https://github.com/cosmos/ics)

- 2019-10-02: [SoK: Communication Across Distributed Ledgers](https://eprint.iacr.org/2019/1128.pdf)

- 2020-01-12: [Coins: A Billion Bitcoin Users](https://coins.github.io/research/coins.pdf)

- 2020-01-21: [Introducing Cross-Chain Group](https://medium.com/cross-chain-group/introducing-cross-chain-group-c9238e62509e)

- 2021-01-28: [Hop: Send Tokens Across Rollups](https://hop.exchange/whitepaper.pdf)

- 2021-08-05: [Introducing the Cross-Chain Interoperability Protocol (CCIP) for Decentralized Inter-Chain Messaging and Token Movements](https://blog.chain.link/introducing-the-cross-chain-interoperability-protocol-ccip/)

- 2021-09-08: [Blockchain Bridges: Building Networks of Cryptonetworks](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8)

- 2021-09-10: [The tradeoffs of cross-chain communication](https://ls.mirror.xyz/5FM0KUurAEkN7yDXLAI8i9kCha_yMlzguVqiHEGMjPU)

- 2021-10-01: [The Interoperability Trilemma](https://medium.com/connext/the-interoperability-trilemma-657c2cf69f17)

- 2021-10-04: [Clusters: how trusted & trust-minimized bridges shape the multi-chain landscape](https://blog.celestia.org/clusters/)

- 2021-10-25: [Across Protocol: Instant Trustless Token Transfers from Roll-up to Mainnet](https://drive.google.com/file/d/1t9tJUjJupLSvHKR8glwLKh8kpBNp5sp1/view)

- 2021-10-26: [Stakechain: A Bitcoin-backed Proof-of-Stake](https://raw.githubusercontent.com/coins/research/master/Bitcoin_backed_Proof_of_Stake.pdf)

- 2022-01-20: [Babylon: Reusing Bitcoin Mining to Enhance Proof-of-Stake Security](https://eprint.iacr.org/2022/076)

# Bonus

- 2016-03-07: [My Sofa is a Sidechain](https://www.ic.unicamp.br/~stolfi/EXPORT/projects/bitcoin/posts/2015-06-10-my-sofa-is-a-sidechain/main.html)

repo_name: john-light/sidechains

mime_type: text/plain


text:
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2018
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtGuiDemo", "QtGuiDemo\QtGuiDemo.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|x64 = Debug|x64
		Release|x64 = Release|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
		{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64
		{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64
		{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		Qt5Version = qt5.9.6
		SolutionGuid = {5CAA91D1-DA89-41FB-AE25-A7D0CD071E8E}
	EndGlobalSection
EndGlobal

mime_type: text/xml


text:
# Yolov4-QtGUI

- Yolov4-QtGUI是基于 [QtGuiDemo](https://github.com/jmu201521121021/QtGuiDemo) 项目开发的可视化目标检测界面，可以简便选择本地图片、摄像头来展示图像处理算法的结果
## 开发软件环境

- **Windows 10**
- **QT 5.9.6**
- **OpenCV 3.4.2**    [download](https://github.com/opencv/opencv/releases/tag/3.4.2)
- **Visual Studio 2017**
- Cuda 10.1 （optional）
- Cudnn >= 7.0 （optional）
## 快速使用demo

下载权重文件：[yolov4_weight](https://pan.baidu.com/s/16js1bfzKFiQ6mJ7NiP_DtA)  提取码：4mic

- CPU Demo：[yolov4_cpu](https://pan.baidu.com/s/1uacNNl6ZL2M3s0GVfkTdVA)    提取码：l3eh
- GPU Demo：[yolov4_gpu](https://pan.baidu.com/s/1c-clykwyKHGQp2ENnJjFoA)    提取码：d6lz

首先将下载的权重文件放置在  **./model**  目录下

然后双击  **./Release**  目录下的  **QtGuiDemo.exe**  即可

## 使用步骤（项目详解请移步博客：[Yolov4-QtGUI](https://blog.csdn.net/weixin_42448226/article/details/105752224)）

- 下载项目：git clone https://github.com/scutlrr/Yolov4-QtGUI.git
- 将 [3rdparty](https://pan.baidu.com/s/1-60BX9eXrKuUbnqHHyKihw) （提取码：f1vo）放置在项目目录下

![项目结构](assets/项目结构.jpg)

- vs打开 **Yolov4-QtGUI\QtGuiDemo.sln**

- **GPU version**

  -  修改属性文件**yolov4.prop**，"链接器”->"输入"->"附加依赖项"->**yolo_cpp_dll.lib**。在“**x64  release**”模式下，菜单栏点击＂生成＂－>＂生成解决方案＂，并将

  -        -  3rdparty\libdarknet\bin 路径下的  pthreadGC2.dll、pthreadVC2.dll

           -  3rdparty\libdarknet\bin\release\gpu 路径下的 yolo_cpp_dll.dll

           -  3rdparty\libopencv\bin 路径下的  opencv_world342.dll

         复制到Yolov4-QtGUI\x64\release目录下

- **CPU version**

  - 修改属性文件**yolov4.prop**，"链接器”->"输入"->"附加依赖项"->**yolo_cpp_dll_cpu.lib**。在＂**x64 release**＂模式下，菜单栏点击＂生成＂－>＂生成解决方案＂，并将

  -        -  3rdparty\libdarknet\bin 路径下的  pthreadGC2.dll、pthreadVC2.dll

           -  3rdparty\libdarknet\bin\release\cpu 路径下的 yolo_cpp_dll.dll

           -  3rdparty\libopencv\bin 路径下的  opencv_world342.dll

         复制到Yolov4-QtGUI\x64\release目录下。

- 运行项目。双击x64\Release目录下的exe文件即可。

## 处理流程

- 将图像处理算法处理之后的图像通过this->InputImage输出到在this->imageLabel控件上
- 本地图片处理：void openPictureSlot()，在这个槽函数处理this->imputImage
- 视频文件和本地摄像头处理：void paintEvent(QPaintEvent *e)，在这个槽函数处理每一帧this->imageLabel

## 结果展示

- 测试图片：

![打开图片](assets/测试图片.png)

- 测试摄像头：

![打开摄像头](assets/测试摄像头.png)


text:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
      <Extensions>qrc;*</Extensions>
      <ParseFiles>false</ParseFiles>
    </Filter>
    <Filter Include="Form Files">
      <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
      <Extensions>ui</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
      <Extensions>qrc;*</Extensions>
      <ParseFiles>false</ParseFiles>
    </Filter>
    <Filter Include="Generated Files">
      <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
      <Extensions>moc;h;cpp</Extensions>
      <SourceControlFiles>False</SourceControlFiles>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="QtGuiDemo.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <QtMoc Include="QtGuiDemo.h">
      <Filter>Header Files</Filter>
    </QtMoc>
  </ItemGroup>
  <ItemGroup>
    <QtUic Include="QtGuiDemo.ui">
      <Filter>Form Files</Filter>
    </QtUic>
  </ItemGroup>
  <ItemGroup>
    <QtRcc Include="QtGuiDemo.qrc">
      <Filter>Resource Files</Filter>
    </QtRcc>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="common.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
</Project>


text:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <QTDIR>D:\vs\qt\5.9.6\msvc2017_64</QTDIR>
    <LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <QTDIR>D:\vs\qt\5.9.6\msvc2017_64</QTDIR>
    <LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
  </PropertyGroup>
</Project>


text:
<RCC>
    <qresource prefix="QtGuiDemo">
    </qresource>
</RCC>


text:
<UI version="4.0" >
 <class>QtGuiDemoClass</class>
 <widget class="QMainWindow" name="QtGuiDemoClass" >
  <property name="objectName" >
   <string notr="true">QtGuiDemoClass</string>
  </property>
  <property name="geometry" >
   <rect>
	<x>0</x>
	<y>0</y>
	<width>600</width>
	<height>400</height>
   </rect>
  </property>
  <property name="windowTitle" >
   <string>QtGuiDemo</string>
  </property>
  <widget class="QMenuBar" name="menuBar" />
  <widget class="QToolBar" name="mainToolBar" />
  <widget class="QWidget" name="centralWidget" />
  <widget class="QStatusBar" name="statusBar" />
 </widget>
 <layoutDefault spacing="6" margin="11" />
 <pixmapfunction></pixmapfunction>
 <resources>
   <include location="QtGuiDemo.qrc"/>
 </resources>
 <connections/>
</UI>


text:
#include "QtGuiDemo.h"
#include"common.h"

#include "QString"
#include "QFileDialog"
#include "QDir"
#include "QDateTime"
#include "QFileInfo"
#include "QProgressDialog"

#include <vector>
#include <queue>
#include <fstream>
#include <thread>
#include <atomic>
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

QtGuiDemo::QtGuiDemo(QWidget *parent):
	QMainWindow(parent)
{
	init_detector();
	ui.setupUi(this);
	initView();
}

QtGuiDemo::~QtGuiDemo()
{
	delete [] this->detector_;
	detector_ = nullptr;
	cleanMenu();
	cleanLayout();
}
void QtGuiDemo::init_detector()
{
	this->detector_ = new Detector(this->cfg_file_, this->weights_file_);
}
void QtGuiDemo::initView()
{
	/* 菜单 */
	initMenu();
	/* 布局 */
	initLayout();
}
/**
* @brief MainWindow::initMenu - 初始化菜单栏
*/
void QtGuiDemo::initMenu()
{

	/* 文件菜单ui设置 */
	openFileMenu = new QMenu(SQ("功能模块"));

	openPictureAction = new QAction(SQ("图片文件"), this);
	connect(openPictureAction, SIGNAL(triggered()), this, SLOT(openPictureSlot()));
	openFileMenu->addAction(openPictureAction);

	openVideoAction = new QAction(SQ("打开视频文件"), this);
	connect(openVideoAction, SIGNAL(triggered()), this, SLOT(openVideoSlot()));
	openFileMenu->addAction(openVideoAction);

	openCaptureAction = new QAction(SQ("打开摄像头"), this);
	connect(openCaptureAction, SIGNAL(triggered()), this, SLOT(openCaptureSlot()));
	openFileMenu->addAction(openCaptureAction);

	/* 将功能模块添加到菜单栏上 */
	QMenuBar *menuBar = this->menuBar();
	menuBar->addMenu(openFileMenu);

	/* LOGO */
	this->setWindowTitle(SQ("目标检测系统"));
}

/**
* @brief MainWindow::initLayout - 初始化控件布局
*/
void QtGuiDemo::initLayout()
{
	/* 图片显示面板 */
	centralWidget = new QWidget(this);
	imageLabel = new  QLabel(centralWidget);
	imageLabel->setScaledContents(true);
	QSize labelSize(SCREEN_WIDTH, SCREEN_HEIGHT);
	imageLabel->setFixedSize(labelSize);
	this->setCentralWidget(centralWidget);
	this->resize(SCREEN_WIDTH, SCREEN_HEIGHT);
	this->show();
}

void QtGuiDemo::cleanMenu()
{
	if (openFileMenu)
	{
		delete openFileMenu;
		openFileMenu = NULL;
	}
	if (openCaptureAction)
	{
		delete openCaptureAction;
		openCaptureAction = NULL;
	}
	if (openVideoAction)
	{
		delete openVideoAction;
		openVideoAction = NULL;
	}

	if (openPictureAction)
	{
		delete openPictureAction;
		openPictureAction = NULL;
	}
}

void QtGuiDemo::cleanLayout()
{

	if (centralWidget)
	{
		delete centralWidget;
		centralWidget = NULL;
	}

}

void QtGuiDemo::setCVMat2QtLabel(const cv::Mat &image, QLabel *qLabel)
{
	cv::Mat showImg;
	cv::cvtColor(image, showImg, CV_BGR2RGB);
	QImage qImg = QImage((const uchar *)(showImg.data),
		showImg.cols, showImg.rows,
		showImg.cols * showImg.channels(),
		QImage::Format_RGB888);
	qLabel->clear();                                //清空控件label
	qLabel->setPixmap(QPixmap::fromImage(qImg));    //label赋值
	qLabel->show();
	qLabel->update();
}

void QtGuiDemo::openPictureSlot()
{
	this->selectMode = 0;
	QString imageFilePath;
	imageFilePath = QFileDialog::getOpenFileName(
		this,
		SQ("选择图片文件"),
		QDir::currentPath(),
		"All files(*.jpg *JPG *.jpeg *.png *.PNG *.gif *.bmp)");																						// 数据检查
	if (QS(imageFilePath).empty())
	{
		qDebug()<< "The imageFilePath is not exit!!!\n";
		return;
	}

	inputImage = cv::imread(QS(imageFilePath));
	auto start = std::chrono::steady_clock::now();
	std::vector<bbox_t> result_vec = this->detector_->detect(inputImage);
	auto end = std::chrono::steady_clock::now();
	std::chrono::duration<double> spent = end - start;
	qDebug() << " Time: " << spent.count() << " sec \n";

	// result_vec = detector->tracking_id(result_vec);    // comment it - if track_id is not required
	draw_boxes(inputImage, result_vec, obj_names, spent.count());

	this->setCVMat2QtLabel(this->inputImage, this->imageLabel);
}

void QtGuiDemo::openVideoSlot()
{

	QString vedioFilePath;
	vedioFilePath = QFileDialog::getOpenFileName(
		this,
		SQ("选择视频文件"),
		QDir::currentPath(),
		"All files(*.mp4 *.MP4 *.AVI *.avi)");																						// 数据检查
	if (QS(vedioFilePath).empty())
	{
		qDebug() << "The VedioFilePath is not exit!!!\n";
		return;
	}

	if (this->capture.isOpened())
	{
		this->capture.release();
	}
	if (!this->capture.open(QS(vedioFilePath)))
	{
			qDebug() << "open video false 0";
	}
	else
	{
		this->selectMode = 1;
		this->isOpenVedio = true;
		qDebug() << "open video file successful 0\n";
	}
}

// 本地摄像头槽
void QtGuiDemo:: openCaptureSlot()
{
	if (openCaptureAction->text() == SQ("打开摄像头"))
	{
		this->selectMode = 2;
		if (!this->capture.open(0))
		{
			if (!this->capture.open(0)) {
				// capture.open(0);
			}
			qDebug() << "open video false 0";

		}
		qDebug() << "open video successful 0\n";
		this->isOpenVedio = true;
		this->openCaptureAction->setText(SQ("关闭摄像头"));

	}
	else
	{
		openCaptureAction->setText(SQ("打开摄像头"));
		this->capture.release();
		this->isOpenVedio = false;
	}
}

// 实时显示视频流
void QtGuiDemo::paintEvent(QPaintEvent *e)
{

	if (this->isOpenVedio && (this->selectMode>0))
	{
		this->capture >> this->inputImage;
		this->setCVMat2QtLabel(inputImage, this->imageLabel);

		auto start = std::chrono::steady_clock::now();
		std::vector<bbox_t> result_vec = this->detector_->detect(this->inputImage);
		auto end = std::chrono::steady_clock::now();
		std::chrono::duration<double> spent = end - start;
		qDebug() << " Time: " << spent.count() << " sec \n";

		// result_vec = detector->tracking_id(result_vec);    // comment it - if track_id is not required
		draw_boxes(this->inputImage, result_vec, obj_names, spent.count());

		this->setCVMat2QtLabel(inputImage, this->imageLabel);
	}

	else if (!this->isOpenVedio && (this->selectMode>0))
	{
		this->imageLabel->clear();
	}
}

std::vector<std::string> QtGuiDemo::objects_names_from_file(std::string const filename) {
	std::ifstream file(filename);
	std::vector<std::string> file_lines;
	if (!file.is_open()) return file_lines;
	for (std::string line; getline(file, line);) file_lines.push_back(line);
	std::cout << "object names loaded \n";
	return file_lines;
}

cv::Scalar QtGuiDemo::obj_id_to_color(int obj_id) {
	int const colors[6][3] = { { 1,0,1 },{ 0,0,1 },{ 0,1,1 },{ 0,1,0 },{ 1,1,0 },{ 1,0,0 } };
	int const offset = obj_id * 123457 % 6;
	int const color_scale = 150 + (obj_id * 123457) % 100;
	cv::Scalar color(colors[offset][0], colors[offset][1], colors[offset][2]);
	color *= color_scale;
	return color;
}


text:
#include "QtGuiDemo.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	QtGuiDemo w;
	w.show();
	return a.exec();
}


text:
#pragma once

#ifndef QT_H
#define QT_H

#include <QtWidgets/QMainWindow>
#include "ui_QtGuiDemo.h"

#include <QMainWindow>
#include <QLabel>
#include <QGridLayout>
#include <QLineEdit>
#include <QComboBox>
#include <QPushButton>
#include <QCheckBox>
#include <QFormLayout>
#include <QObject>
#include <QMetaEnum>
#include <QDebug>
#include <QIcon>

#include <string>
#include <qstring.h>
#include <opencv2/opencv.hpp>
#include "yolo_v2_class.hpp"

#define SCREEN_WIDTH 1920
#define SCREEN_HEIGHT 1080

class QtGuiDemo : public QMainWindow
{
	Q_OBJECT

public:
	QtGuiDemo(QWidget *parent = Q_NULLPTR);
	~QtGuiDemo();
	/**opencv mat 图像转为qImage, 显示在qLabel上**/
	void setCVMat2QtLabel(const cv::Mat &image, QLabel *qLabel);
	std::vector<std::string> objects_names_from_file(std::string const filename);
	cv::Scalar obj_id_to_color(int obj_id);
	void init_detector();
// QT 界面初始化和槽
public slots:
	/* 界面*/
	void initView();
	void initMenu();
	void cleanMenu();
	void initLayout();
	void cleanLayout();
	/* 菜单槽函数 */
	void openVideoSlot();				// 打开本地视频文件槽
	void openPictureSlot();				// 打开图片槽
	void openCaptureSlot();
	void paintEvent(QPaintEvent *e);	// 实时显示槽

private:
	Ui::QtGuiDemoClass ui;
	/* 菜单栏 */
	QMenu *openFileMenu;

	QAction *openCaptureAction;			// 打开摄像头
	QAction *openVideoAction;			// 打开本地视频文件
	QAction *openPictureAction;			// 打开图片
	QLabel *imageLabel;					// 显示图片Label控件

	QWidget *centralWidget;

	cv::VideoCapture capture;
	cv::Mat inputImage;
	cv::Mat outputImage;

	std::string  names_file_ = "../data/coco.names";
	std::string  cfg_file_ = "../cfg/yolov4.cfg";
	std::string  weights_file_ = "../model/yolov4.weights";

	std::vector<std::string> obj_names = objects_names_from_file(names_file_);
	Detector *detector_;

	// 视频开关
	bool isOpenVedio = false;
	// 选择模式 0. 打开图片文件 2.打开本地视频 3.打开本地摄像头
	int selectMode;
};

#endif // QT_H


text:
#pragma once
#include <string>
#include <qstring.h>
#include <opencv2/opencv.hpp>
#include "yolo_v2_class.hpp"

#define SQ(str) str2qstr(str)
#define QS(qstr) std::string(qstr2str(QString(qstr)))

inline QString str2qstr(const std::string& str)
{
	return QString::fromLocal8Bit(str.data());
}

inline std::string qstr2str(const QString& qstr)
{
	QByteArray cdata = qstr.toLocal8Bit();
	return std::string(cdata);
}

void draw_boxes(cv::Mat mat_img, std::vector<bbox_t> result_vec, std::vector<std::string> obj_names, double spendTime, int current_det_fps = -1, int current_cap_fps = -1)
{
	int const colors[6][3] = { { 1,0,1 },{ 0,0,1 },{ 0,1,1 },{ 0,1,0 },{ 1,1,0 },{ 1,0,0 } };

	for (auto &i : result_vec) {
		cv::Scalar color(0, 255, 0);
		cv::rectangle(mat_img, cv::Rect(i.x, i.y, i.w, i.h), color, 2);
		std::string obj_name = obj_names[i.obj_id];
		cv::Size const text_size = getTextSize(obj_name, cv::FONT_HERSHEY_COMPLEX_SMALL, 1.2, 2, 0);
		int const max_width = (text_size.width > i.w + 2) ? text_size.width - 5 : (i.w + 2);
		cv::rectangle(mat_img, cv::Point2f(std::max((int)i.x - 1, 0), std::max((int)i.y - 30, 0)),
			cv::Point2f(std::min((int)i.x + max_width, mat_img.cols - 1), std::min((int)i.y, mat_img.rows - 1)),
			color, CV_FILLED, 8, 0);
		putText(mat_img, obj_name, cv::Point2f(i.x, i.y - 10), cv::FONT_HERSHEY_COMPLEX_SMALL, 1.2, cv::Scalar(0, 0, 0), 2);
	}
	std::string  spend = QS(QString::number(spendTime, 10, 4));
	putText(mat_img, "time:" + spend + "s", cv::Point2f(0, 30), cv::FONT_HERSHEY_COMPLEX_SMALL, 1.2, cv::Scalar(0, 0, 0), 2);
	if (current_det_fps >= 0 && current_cap_fps >= 0) {
		std::string fps_str = "FPS detection: " + std::to_string(current_det_fps) + "   FPS capture: " + std::to_string(current_cap_fps);
		putText(mat_img, fps_str, cv::Point2f(10, 20), cv::FONT_HERSHEY_COMPLEX_SMALL, 1.2, cv::Scalar(50, 255, 0), 2);
	}
}


text:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
    <Keyword>Qt4VSv1.0</Keyword>
    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v141</PlatformToolset>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v141</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <PropertyGroup Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">
    <QtMsBuild>$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
  </PropertyGroup>
  <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
    <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
  </Target>
  <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
    <Import Project="$(QtMsBuild)\qt.props" />
  </ImportGroup>
  <ImportGroup Label="ExtensionSettings" />
  <ImportGroup Label="Shared" />
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="..\config\yolov4_d.props" />
    <Import Project="..\config\opencv3_d.props" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="..\config\yolov4.props" />
    <Import Project="..\config\opencv3.props" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <MultiProcessorCompilation>true</MultiProcessorCompilation>
      <PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_CORE_LIB;QT_GUI_LIB;QT_UITOOLS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <Optimization>Disabled</Optimization>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
      <AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AdditionalDependencies>qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5UiToolsd.lib;Qt5Widgetsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
    <QtMoc>
      <OutputFile>.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</OutputFile>
      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
      <IncludePath>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</IncludePath>
      <Define>UNICODE;WIN32;WIN64;QT_CORE_LIB;QT_GUI_LIB;QT_UITOOLS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</Define>
      <QTDIR>$(QTDIR)</QTDIR>
    </QtMoc>
    <QtUic>
      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
      <OutputFile>.\GeneratedFiles\ui_%(Filename).h</OutputFile>
      <QTDIR>$(QTDIR)</QTDIR>
    </QtUic>
    <QtRcc>
      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
      <OutputFile>.\GeneratedFiles\qrc_%(Filename).cpp</OutputFile>
      <QTDIR>$(QTDIR)</QTDIR>
    </QtRcc>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <MultiProcessorCompilation>true</MultiProcessorCompilation>
      <PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_UITOOLS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <DebugInformationFormat />
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
      <AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <GenerateDebugInformation>false</GenerateDebugInformation>
      <AdditionalDependencies>qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5UiTools.lib;Qt5Widgets.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
    <QtMoc>
      <OutputFile>.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</OutputFile>
      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
      <IncludePath>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</IncludePath>
      <Define>UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_UITOOLS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</Define>
      <QTDIR>$(QTDIR)</QTDIR>
    </QtMoc>
    <QtUic>
      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
      <OutputFile>.\GeneratedFiles\ui_%(Filename).h</OutputFile>
      <QTDIR>$(QTDIR)</QTDIR>
    </QtUic>
    <QtRcc>
      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
      <OutputFile>.\GeneratedFiles\qrc_%(Filename).cpp</OutputFile>
      <QTDIR>$(QTDIR)</QTDIR>
    </QtRcc>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp" />
    <ClCompile Include="QtGuiDemo.cpp" />
  </ItemGroup>
  <ItemGroup>
    <QtMoc Include="QtGuiDemo.h" />
  </ItemGroup>
  <ItemGroup>
    <QtUic Include="QtGuiDemo.ui" />
  </ItemGroup>
  <ItemGroup>
    <QtRcc Include="QtGuiDemo.qrc" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="common.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
    <Import Project="$(QtMsBuild)\qt.targets" />
  </ImportGroup>
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
  <ProjectExtensions>
    <VisualStudio>
      <UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_x64="qt5.9.6" MocOptions="" />
    </VisualStudio>
  </ProjectExtensions>
</Project>


text:
/********************************************************************************
** Form generated from reading UI file 'QtGuiDemo.ui'
**
** Created by: Qt User Interface Compiler version 5.9.6
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_QTGUIDEMO_H
#define UI_QTGUIDEMO_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_QtGuiDemoClass
{
public:
    QMenuBar *menuBar;
    QToolBar *mainToolBar;
    QWidget *centralWidget;
    QStatusBar *statusBar;

    void setupUi(QMainWindow *QtGuiDemoClass)
    {
        if (QtGuiDemoClass->objectName().isEmpty())
            QtGuiDemoClass->setObjectName(QStringLiteral("QtGuiDemoClass"));
        QtGuiDemoClass->resize(600, 400);
        menuBar = new QMenuBar(QtGuiDemoClass);
        menuBar->setObjectName(QStringLiteral("menuBar"));
        QtGuiDemoClass->setMenuBar(menuBar);
        mainToolBar = new QToolBar(QtGuiDemoClass);
        mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
        QtGuiDemoClass->addToolBar(mainToolBar);
        centralWidget = new QWidget(QtGuiDemoClass);
        centralWidget->setObjectName(QStringLiteral("centralWidget"));
        QtGuiDemoClass->setCentralWidget(centralWidget);
        statusBar = new QStatusBar(QtGuiDemoClass);
        statusBar->setObjectName(QStringLiteral("statusBar"));
        QtGuiDemoClass->setStatusBar(statusBar);

        retranslateUi(QtGuiDemoClass);

        QMetaObject::connectSlotsByName(QtGuiDemoClass);
    } // setupUi

    void retranslateUi(QMainWindow *QtGuiDemoClass)
    {
        QtGuiDemoClass->setWindowTitle(QApplication::translate("QtGuiDemoClass", "QtGuiDemo", Q_NULLPTR));
    } // retranslateUi

};

namespace Ui {
    class QtGuiDemoClass: public Ui_QtGuiDemoClass {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_QTGUIDEMO_H


text:
/****************************************************************************
** Resource object code
**
** Created by: The Resource Compiler for Qt version 5.9.6
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#ifdef QT_NAMESPACE
#  define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
#  define QT_RCC_MANGLE_NAMESPACE0(x) x
#  define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
#  define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
#  define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
        QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
#else
#   define QT_RCC_PREPEND_NAMESPACE(name) name
#   define QT_RCC_MANGLE_NAMESPACE(name) name
#endif

#ifdef QT_NAMESPACE
namespace QT_NAMESPACE {
#endif

#ifdef QT_NAMESPACE
}
#endif

int QT_RCC_MANGLE_NAMESPACE(qInitResources_QtGuiDemo)();
int QT_RCC_MANGLE_NAMESPACE(qInitResources_QtGuiDemo)()
{
    return 1;
}

int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_QtGuiDemo)();
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_QtGuiDemo)()
{
    return 1;
}

namespace {
   struct initializer {
       initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_QtGuiDemo)(); }
       ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_QtGuiDemo)(); }
   } dummy;
}


text:
/****************************************************************************
** Meta object code from reading C++ file 'QtGuiDemo.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.9.6)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#include "../../QtGuiDemo.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'QtGuiDemo.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.9.6. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_QtGuiDemo_t {
    QByteArrayData data[13];
    char stringdata0[134];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
    qptrdiff(offsetof(qt_meta_stringdata_QtGuiDemo_t, stringdata0) + ofs \
        - idx * sizeof(QByteArrayData)) \
    )
static const qt_meta_stringdata_QtGuiDemo_t qt_meta_stringdata_QtGuiDemo = {
    {
QT_MOC_LITERAL(0, 0, 9), // "QtGuiDemo"
QT_MOC_LITERAL(1, 10, 8), // "initView"
QT_MOC_LITERAL(2, 19, 0), // ""
QT_MOC_LITERAL(3, 20, 8), // "initMenu"
QT_MOC_LITERAL(4, 29, 9), // "cleanMenu"
QT_MOC_LITERAL(5, 39, 10), // "initLayout"
QT_MOC_LITERAL(6, 50, 11), // "cleanLayout"
QT_MOC_LITERAL(7, 62, 13), // "openVideoSlot"
QT_MOC_LITERAL(8, 76, 15), // "openPictureSlot"
QT_MOC_LITERAL(9, 92, 15), // "openCaptureSlot"
QT_MOC_LITERAL(10, 108, 10), // "paintEvent"
QT_MOC_LITERAL(11, 119, 12), // "QPaintEvent*"
QT_MOC_LITERAL(12, 132, 1) // "e"

    },
    "QtGuiDemo\0initView\0\0initMenu\0cleanMenu\0"
    "initLayout\0cleanLayout\0openVideoSlot\0"
    "openPictureSlot\0openCaptureSlot\0"
    "paintEvent\0QPaintEvent*\0e"
};
#undef QT_MOC_LITERAL

static const uint qt_meta_data_QtGuiDemo[] = {

 // content:
       7,       // revision
       0,       // classname
       0,    0, // classinfo
       9,   14, // methods
       0,    0, // properties
       0,    0, // enums/sets
       0,    0, // constructors
       0,       // flags
       0,       // signalCount

 // slots: name, argc, parameters, tag, flags
       1,    0,   59,    2, 0x0a /* Public */,
       3,    0,   60,    2, 0x0a /* Public */,
       4,    0,   61,    2, 0x0a /* Public */,
       5,    0,   62,    2, 0x0a /* Public */,
       6,    0,   63,    2, 0x0a /* Public */,
       7,    0,   64,    2, 0x0a /* Public */,
       8,    0,   65,    2, 0x0a /* Public */,
       9,    0,   66,    2, 0x0a /* Public */,
      10,    1,   67,    2, 0x0a /* Public */,

 // slots: parameters
    QMetaType::Void,
    QMetaType::Void,
    QMetaType::Void,
    QMetaType::Void,
    QMetaType::Void,
    QMetaType::Void,
    QMetaType::Void,
    QMetaType::Void,
    QMetaType::Void, 0x80000000 | 11,   12,

       0        // eod
};

void QtGuiDemo::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    if (_c == QMetaObject::InvokeMetaMethod) {
        QtGuiDemo *_t = static_cast<QtGuiDemo *>(_o);
        Q_UNUSED(_t)
        switch (_id) {
        case 0: _t->initView(); break;
        case 1: _t->initMenu(); break;
        case 2: _t->cleanMenu(); break;
        case 3: _t->initLayout(); break;
        case 4: _t->cleanLayout(); break;
        case 5: _t->openVideoSlot(); break;
        case 6: _t->openPictureSlot(); break;
        case 7: _t->openCaptureSlot(); break;
        case 8: _t->paintEvent((*reinterpret_cast< QPaintEvent*(*)>(_a[1]))); break;
        default: ;
        }
    }
}

const QMetaObject QtGuiDemo::staticMetaObject = {
    { &QMainWindow::staticMetaObject, qt_meta_stringdata_QtGuiDemo.data,
      qt_meta_data_QtGuiDemo,  qt_static_metacall, nullptr, nullptr}
};

const QMetaObject *QtGuiDemo::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}

void *QtGuiDemo::qt_metacast(const char *_clname)
{
    if (!_clname) return nullptr;
    if (!strcmp(_clname, qt_meta_stringdata_QtGuiDemo.stringdata0))
        return static_cast<void*>(this);
    return QMainWindow::qt_metacast(_clname);
}

int QtGuiDemo::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QMainWindow::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 9)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 9;
    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
        if (_id < 9)
            *reinterpret_cast<int*>(_a[0]) = -1;
        _id -= 9;
    }
    return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE


text:
[net]
# Testing
#batch=1
#subdivisions=1
# Training
batch=64
subdivisions=8
width=608
height=608
channels=3
momentum=0.949
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.00261
burn_in=1000
max_batches = 500500
policy=steps
steps=400000,450000
scales=.1,.1

#cutmix=1
mosaic=1

#:104x104 54:52x52 85:26x26 104:13x13 for 416

[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=mish

# Downsample

[convolutional]
batch_normalize=1
filters=64
size=3
stride=2
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[route]
layers = -2

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=32
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[route]
layers = -1,-7

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

# Downsample

[convolutional]
batch_normalize=1
filters=128
size=3
stride=2
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[route]
layers = -2

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=mish

[route]
layers = -1,-10

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

# Downsample

[convolutional]
batch_normalize=1
filters=256
size=3
stride=2
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[route]
layers = -2

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=mish

[route]
layers = -1,-28

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

# Downsample

[convolutional]
batch_normalize=1
filters=512
size=3
stride=2
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[route]
layers = -2

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=mish

[route]
layers = -1,-28

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

# Downsample

[convolutional]
batch_normalize=1
filters=1024
size=3
stride=2
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

[route]
layers = -2

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=mish

[shortcut]
from=-3
activation=linear

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=mish

[route]
layers = -1,-16

[convolutional]
batch_normalize=1
filters=1024
size=1
stride=1
pad=1
activation=mish

##########################

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

### SPP ###
[maxpool]
stride=1
size=5

[route]
layers=-2

[maxpool]
stride=1
size=9

[route]
layers=-4

[maxpool]
stride=1
size=13

[route]
layers=-1,-3,-5,-6
### End SPP ###

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[upsample]
stride=2

[route]
layers = 85

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[route]
layers = -1, -3

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[upsample]
stride=2

[route]
layers = 54

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[route]
layers = -1, -3

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=256
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=256
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

##########################

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=256
activation=leaky

[convolutional]
size=1
stride=1
pad=1
filters=255
activation=linear

[yolo]
mask = 0,1,2
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
scale_x_y = 1.2
iou_thresh=0.213
cls_normalizer=1.0
iou_normalizer=0.07
iou_loss=ciou
nms_kind=greedynms
beta_nms=0.6

[route]
layers = -4

[convolutional]
batch_normalize=1
size=3
stride=2
pad=1
filters=256
activation=leaky

[route]
layers = -1, -16

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky

[convolutional]
size=1
stride=1
pad=1
filters=255
activation=linear

[yolo]
mask = 3,4,5
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
scale_x_y = 1.1
iou_thresh=0.213
cls_normalizer=1.0
iou_normalizer=0.07
iou_loss=ciou
nms_kind=greedynms
beta_nms=0.6

[route]
layers = -4

[convolutional]
batch_normalize=1
size=3
stride=2
pad=1
filters=512
activation=leaky

[route]
layers = -1, -37

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[convolutional]
size=1
stride=1
pad=1
filters=255
activation=linear

[yolo]
mask = 6,7,8
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
scale_x_y = 1.05
iou_thresh=0.213
cls_normalizer=1.0
iou_normalizer=0.07
iou_loss=ciou
nms_kind=greedynms
beta_nms=0.6


text:
person
bicycle
car
motorbike
aeroplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
sofa
pottedplant
bed
diningtable
toilet
tvmonitor
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush


text:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <IncludePath>..\3rdparty\libdarknet\include;$(IncludePath)</IncludePath>
    <LibraryPath>..\3rdparty\libdarknet\lib;$(LibraryPath)</LibraryPath>
    <_PropertySheetDisplayName>yolov4</_PropertySheetDisplayName>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <Link>
      <AdditionalDependencies>yolo_cpp_dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
    <ClCompile>
      <PreprocessorDefinitions>OPENCV</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>
  <ItemGroup />
</Project>


text:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <IncludePath>..\3rdparty\libopencv\include;..\3rdparty\libopencv\include\opencv;..\3rdparty\libopencv\include\pencv2;$(IncludePath)</IncludePath>
    <LibraryPath>..\3rdparty\libopencv\lib;$(LibraryPath)</LibraryPath>
    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <Link>
      <AdditionalDependencies>opencv_world342.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup />
</Project>


text:
if (!$env:SCOOP_HOME) { $env:SCOOP_HOME = Resolve-Path (scoop prefix scoop) }
. "$env:SCOOP_HOME\test\Import-Bucket-Tests.ps1"

repo_name: ScoopInstaller/BucketTemplate

repo_language: PowerShell


text:
# Scoop Bucket Template

<!-- Uncomment the following line after replacing placeholders -->
<!-- [![Tests](https://github.com/<username>/<bucketname>/actions/workflows/ci.yml/badge.svg)](https://github.com/<username>/<bucketname>/actions/workflows/ci.yml) [![Excavator](https://github.com/<username>/<bucketname>/actions/workflows/excavator.yml/badge.svg)](https://github.com/<username>/<bucketname>/actions/workflows/excavator.yml) -->

Template bucket for [Scoop](https://scoop.sh), the Windows command-line installer.

## How do I use this template?

1. Generate your own copy of this repository with the "Use this template"
   button.
2. Allow all GitHub Actions:
   - Navigate to `Settings` - `Actions` - `General` - `Actions permissions`.
   - Select `Allow all actions and reusable workflows`.
   - Then `Save`.
3. Allow writing to the repository from within GitHub Actions:
   - Navigate to `Settings` - `Actions` - `General` - `Workflow permissions`.
   - Select `Read and write permissions`.
   - Then `Save`.
4. Document the bucket in `README.md`.
5. Replace the placeholder repository string in `bin/auto-pr.ps1`.
6. Create new manifests by copying `bucket/app-name.json.template` to
   `bucket/<app-name>.json`.
7. Commit and push changes.

## How do I install these manifests?

After manifests have been committed and pushed, run the following:

```pwsh
scoop bucket add <bucketname> https://github.com/<username>/<bucketname>
scoop install <bucketname>/<manifestname>
```

## How do I contribute new manifests?

To make a new manifest contribution, please read the [Contributing
Guide](https://github.com/ScoopInstaller/.github/blob/main/.github/CONTRIBUTING.md)
and [App Manifests](https://github.com/ScoopInstaller/Scoop/wiki/App-Manifests)
wiki page.


text:
<!-- Provide a general summary of your changes in the title above -->

<!--
  By opening this PR you confirm that you have searched for similar issues/PRs here already.
  Failing to do so will most likely result in closing of this PR without any explanation.
  It is also mandatory to open a relevant issue (either Package Request or Bug Report) for
  discussion with the maintainers, before creating any new PR.
  Read the contributing guide first to save both your and our time.
-->

Closes #XXXX
<!-- or -->
Relates to #XXXX

- [ ] I have read the [Contributing Guide](https://github.com/ScoopInstaller/.github/blob/main/.github/CONTRIBUTING.md).


text:
name: 📦 Package Request
description: Open an issue about a missing package.
title: "[Request]: "
labels: ["package-request"]
body:
- type: checkboxes
  attributes:
    label: Prerequisites
    options:
    - label: I have searched all issues/PRs to ensure it has not already been reported or fixed.
      required: true
- type: checkboxes
  attributes:
    label: Criteria
    description: For a package to be acceptable in this bucket, it should be
    options:
    - label: Criteria 1
      required: true
    - label: Criteria 2
      required: true
    - label: Criteria 3
      required: true
- type: input
  attributes:
    label: Name
    description: Name of the package
  validations:
    required: true
- type: input
  attributes:
    label: Description
    description: Clear and concise details of what it is
  validations:
    required: true
- type: input
  attributes:
    label: Homepage
    description: URI of the package's homepage
  validations:
    required: true
- type: input
  attributes:
    label: Download Link(s)
    description: URI(s) of the package's download(s)
  validations:
    required: true
- type: textarea
  attributes:
    label: Some Indication of Popularity/Repute
    description: GitHub stars/software reviews etc.
  validations:
    required: true


text:
name: 🔢 Hash Error
description: Open an issue about a package's hash is incorrect.
labels: ["bug"]
body:
- type: checkboxes
  attributes:
    label: Prerequisites
    options:
    - label: I have used the predefined issue title. (e.g. "xxx@xxx: hash check failed")
      required: true
    - label: I have verified that I am using the latest version of Scoop and corresponding bucket.
      required: true
- type: input
  attributes:
    label: Package Name and Version
    description: Name and version of package (install name) which has incorrect hash.
    placeholder: e.g. 7zip@21.00 (not '7-Zip')
  validations:
    required: true


text:
blank_issues_enabled: true
contact_links:
  - name: Scoop Community Support
    url: https://github.com/ScoopInstaller/Scoop/discussions
    about: Please ask Scoop related questions here.


text:
name: 🐛 Bug Report
description: Open an issue about a bug that needs fixing.
title: "[Bug]: "
labels: ["bug"]
body:
- type: checkboxes
  attributes:
    label: Prerequisites
    options:
    - label: I have written a descriptive issue title.
      required: true
    - label: I have searched all issues/PRs to ensure it has not already been reported or fixed.
      required: true
    - label: I have verified that I am using the latest version of Scoop and corresponding bucket.
      required: true
- type: input
  attributes:
    label: Package Name
    description: Name of package (install name) which has bug(s)
    placeholder: e.g. 7zip (not '7-Zip')
  validations:
    required: true
- type: textarea
  attributes:
    label: Expected/Current Behaviour
    description: A clear and concise description of what you expected to happen and what actually happen.
    placeholder: I am experiencing a problem with X. I think Y should be happening but Z is actually happening.
  validations:
    required: true
- type: textarea
  attributes:
    label: Steps to Reproduce
    description: List of steps, sample code or failing test that reproduces the behavior.
    render: console
    placeholder: |
      PS> scoop install tests/meson
      Installing 'meson' (0.61.1) [64bit]
      Loading meson-0.61.1-64.msi from cache.
      Checking hash of meson-0.61.1-64.msi ... ok.
      Extracting meson-0.61.1-64.msi ... done.
      Running installer script...
      Linking D:\Scoop\apps\meson\current => D:\Scoop\apps\meson\0.61.1
      Creating shim for 'meson'.
      Can't shim 'meson.exe': File doesn't exist.
  validations:
    required: true
- type: textarea
  attributes:
    label: Possible Solution
    description: Do you have some suggestions on a fix for the bug?
    placeholder: I am experiencing a problem with X. I think Y should be happening but Z is actually happening.
  validations:
    required: true
- type: textarea
  attributes:
    label: Scoop and Buckets Version
    description: Paste verbatim output from `scoop --version` below.
    render: console
    placeholder: |
      PS> scoop --version
      Current Scoop version:
      c60df9cd (HEAD -> develop, origin/develop) docs(changelog): Prepare for version 0.3.1 (#5248)

      'extras' bucket:
      ea314b213 (HEAD -> master, origin/master, origin/HEAD) lazygit: Update to version 0.36.0

      'main' bucket:
      c6e688d4d (HEAD -> master, origin/master, origin/HEAD) x265: Update to version 3.5+68-40e37bc
  validations:
    required: true
- type: textarea
  attributes:
    label: Scoop Config
    description: Paste verbatim output from `scoop config` below.
    render: console
    placeholder: |
      PS> scoop config

      last_update            : 2022/11/14 22:05:50
      scoop_repo             : https://github.com/ScoopInstaller/Scoop
      scoop_branch           : develop
      use_lessmsi            : True
      aria2-enabled          : True
      aria2-warning-enabled  : False
  validations:
    required: true
- type: textarea
  attributes:
    label: PowerShell Version
    description: Paste verbatim output from `$PSVersionTable` below.
    render: console
    placeholder: |
      PS> $PSVersionTable

      Name                           Value
      ----                           -----
      PSVersion                      7.3.0
      PSEdition                      Core
      GitCommitId                    7.3.0
      OS                             Microsoft Windows 10.0.25236
      Platform                       Win32NT
      PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
      PSRemotingProtocolVersion      2.3
      SerializationVersion           1.1.0.1
      WSManStackVersion              3.0
  validations:
    required: true
- type: textarea
  attributes:
    label: Additional Softwares
    description: List any additional software that you are using and may be related to this bug.
  validations:
    required: false


text:
on:
  issues:
    types: [opened, labeled]
name: Issues
jobs:
  issueHandler:
    name: IssueHandler
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@main
      - name: IssueHandler
        uses: ScoopInstaller/GithubActions@main
        if: github.event.action == 'opened' || (github.event.action == 'labeled' && contains(github.event.issue.labels.*.name, 'verify'))
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


text:
name: Tests

on:
  push:
    branches:
      - 'main'
      - 'master'
  pull_request:
  workflow_dispatch:

jobs:
  test_powershell:
    name: WindowsPowerShell
    runs-on: windows-latest
    steps:
      - name: Checkout Bucket
        uses: actions/checkout@main
        with:
          fetch-depth: 2
          path: my_bucket
      - name: Checkout Scoop
        uses: actions/checkout@main
        with:
          repository: ScoopInstaller/Scoop
          path: scoop_core
      - name: Init Test Suite
        uses: potatoqualitee/psmodulecache@v5.1
        with:
          modules-to-cache: BuildHelpers
          shell: powershell
      - name: Test Bucket
        shell: powershell
        run: |
          $env:SCOOP_HOME="$(Convert-Path '.\scoop_core')"
          .\my_bucket\bin\test.ps1
  test_pwsh:
    name: PowerShell
    runs-on: windows-latest
    steps:
      - name: Checkout Bucket
        uses: actions/checkout@main
        with:
          fetch-depth: 2
          path: my_bucket
      - name: Checkout Scoop
        uses: actions/checkout@main
        with:
          repository: ScoopInstaller/Scoop
          path: scoop_core
      - name: Init Test Suite
        uses: potatoqualitee/psmodulecache@v5.1
        with:
          modules-to-cache: BuildHelpers
          shell: pwsh
      - name: Test Bucket
        shell: pwsh
        run: |
          $env:SCOOP_HOME="$(Convert-Path '.\scoop_core')"
          .\my_bucket\bin\test.ps1


text:
on:
  issue_comment:
    types: [created]
name: Commented Pull Request
jobs:
  pullRequestHandler:
    name: PullRequestHandler
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@main
      - name: PullRequestHandler
        uses: ScoopInstaller/GithubActions@main
        if: startsWith(github.event.comment.body, '/verify')
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


text:
on:
  pull_request:
    types: [opened]
name: Pull Requests
jobs:
  pullRequestHandler:
    name: PullRequestHandler
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@main
      - name: PullRequestHandler
        uses: ScoopInstaller/GithubActions@main
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


text:
on:
  workflow_dispatch:
  schedule:
    # run every 4 hours
    - cron: '20 */4 * * *'
name: Excavator
jobs:
  excavate:
    name: Excavate
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@main
      - name: Excavate
        uses: ScoopInstaller/GithubActions@main
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SKIP_UPDATED: 1


text:
// Configure PSScriptAnalyzer settings
{
    "[powershell]": {
        "editor.formatOnSave": true
    },
    "powershell.scriptAnalysis.settingsPath": "PSScriptAnalyzerSettings.psd1",
    "powershell.codeFormatting.preset": "OTBS",
    "powershell.codeFormatting.alignPropertyValuePairs": true,
    "powershell.codeFormatting.ignoreOneLineBlock": true,
    "json.schemas": [
        {
            "url": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json",
            "fileMatch": [
                "bucket/**/*.json"
            ]
        }
    ],
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "**/tmp": true
    }
}


text:
#Requires -Version 5.1
#Requires -Modules @{ ModuleName = 'BuildHelpers'; ModuleVersion = '2.0.1' }
#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.2.0' }

$pesterConfig = New-PesterConfiguration -Hashtable @{
    Run    = @{
        Path     = "$PSScriptRoot/.."
        PassThru = $true
    }
    Output = @{
        Verbosity = 'Detailed'
    }
}
$result = Invoke-Pester -Configuration $pesterConfig
exit $result.FailedCount


text:
if (!$env:SCOOP_HOME) { $env:SCOOP_HOME = Convert-Path (scoop prefix scoop) }
$formatjson = "$env:SCOOP_HOME/bin/formatjson.ps1"
$path = "$PSScriptRoot/../bucket" # checks the parent dir
& $formatjson -Dir $path @Args


text:
if (!$env:SCOOP_HOME) { $env:SCOOP_HOME = Convert-Path (scoop prefix scoop) }
$checkhashes = "$env:SCOOP_HOME/bin/checkhashes.ps1"
$dir = "$PSScriptRoot/../bucket" # checks the parent dir
& $checkhashes -Dir $dir @Args


text:
if (!$env:SCOOP_HOME) { $env:SCOOP_HOME = Convert-Path (scoop prefix scoop) }
$checkver = "$env:SCOOP_HOME/bin/checkver.ps1"
$dir = "$PSScriptRoot/../bucket" # checks the parent dir
& $checkver -Dir $dir @Args


text:
param(
    # overwrite upstream param
    [String]$upstream = "<username>/<bucketname>:main"
)

if (!$env:SCOOP_HOME) { $env:SCOOP_HOME = Convert-Path (scoop prefix scoop) }
$autopr = "$env:SCOOP_HOME/bin/auto-pr.ps1"
$dir = "$PSScriptRoot/../bucket" # checks the parent dir
& $autopr -Dir $dir -Upstream $Upstream @Args


text:
if (!$env:SCOOP_HOME) { $env:SCOOP_HOME = Convert-Path (scoop prefix scoop) }
$missing_checkver = "$env:SCOOP_HOME/bin/missing-checkver.ps1"
$dir = "$PSScriptRoot/../bucket" # checks the parent dir
& $missing_checkver -Dir $dir @Args


text:
if (!$env:SCOOP_HOME) { $env:SCOOP_HOME = Convert-Path (scoop prefix scoop) }
$checkurls = "$env:SCOOP_HOME/bin/checkurls.ps1"
$dir = "$PSScriptRoot/../bucket" # checks the parent dir
& $checkurls -Dir $dir @Args


text:
{
  pkgs ? (import (fetchTarball "https://github.com/NixOS/nixpkgs-channels/tarball/c75de8bc12cc7e713206199e5ca30b224e295041") {}),
  mavenixLib ? import ./mavenix.nix { inherit pkgs; },
}: with pkgs;

let
  inherit (mavenixLib) name version;
  homepage = "https://github.com/nix-community/mavenix";
  download = "${homepage}/tarball/v${version}";
  gen-header = "# This file has been generated by ${name}.";

  default-tmpl = writeText "default-tmpl.nix" ''
    ${gen-header} Configure the build here!
    let
      mavenix-src = %%env%%;
    in {
      # pkgs is pinned to 19.09 in mavenix-src,
      # replace/invoke with <nixpkgs> or /path/to/your/nixpkgs_checkout
      pkgs ? (import mavenix-src {}).pkgs,
      mavenix ? import mavenix-src { inherit pkgs; },
      src ? %%src%%,
      doCheck ? false,
    }: mavenix.buildMaven {
      inherit src doCheck;
      infoFile = ./mavenix.lock;

      # Add build dependencies
      #
      #buildInputs = with pkgs; [ git makeWrapper ];

      # Set build environment variables
      #
      #MAVEN_OPTS = "-Dfile.encoding=UTF-8";

      # Attributes are passed to the underlying `stdenv.mkDerivation`, so build
      #   hooks can be set here also.
      #
      #postInstall = '''
      #  makeWrapper ''${pkgs.jre8_headless}/bin/java $out/bin/my-bin \
      #    --add-flags "-jar $out/share/java/my-proj.jar"
      #''';

      # Add extra maven dependencies which might not have been picked up
      #   automatically
      #
      #deps = [
      #  { path = "org/group-id/artifactId/version/file.jar"; sha1 = "0123456789abcdef"; }
      #  { path = "org/group-id/artifactId/version/file.pom"; sha1 = "123456789abcdef0"; }
      #];

      # Add dependencies on other mavenix derivations
      #
      #drvs = [ (import ../other/mavenix/derivation {}) ];

      # Override which maven package to build with
      #
      #maven = maven.overrideAttrs (_: { jdk = pkgs.oraclejdk10; });

      # Override remote repository URLs and settings.xml
      #
      #remotes = { central = "https://repo.maven.apache.org/maven2"; };
      #settings = ./settings.xml;
    }
  '';
in mavenixLib // {
  cli = stdenv.mkDerivation {
    inherit name;
    src = lib.cleanSource ./.;

    buildInputs = [ makeWrapper ];

    phases = [ "unpackPhase" "installPhase" "fixupPhase" ];
    installPhase = ''
      mkdir -p $out/bin
      cp mvnix-init mvnix-update $out/bin
      wrapProgram $out/bin/mvnix-init \
        --set CONFIG_TEMPLATE  ${default-tmpl} \
        --set MAVENIX_SCRIPT   ${./mavenix.nix} \
        --set MAVENIX_DOWNLOAD ${download} \
        --set MAVENIX_VERSION ${version} \
        --prefix PATH : ${lib.makeBinPath [ nix coreutils yq ]}
      wrapProgram $out/bin/mvnix-update \
        --set MAVENIX_VERSION ${version} \
        --prefix PATH : ${lib.makeBinPath [ nix coreutils jq yq mktemp ]}
    '';

    meta = with lib; {
      inherit homepage;
      description = "Mavenix: deterministic builds for Maven using Nix?";
      license = licenses.unlicense;
      maintainers = [ { email = "me@icetan.org"; github = "icetan"; name = "Christopher Fredén"; } ];
    };
  };
}

repo_name: nix-community/mavenix

repo_language: Nix


text:
#!/bin/bash
set -e

usage() {
  # shellcheck disable=SC2015
  test "$1" && echo -e Error: "$1"\\n || true
  cat >&2 <<EOF
  Usage: mvnix-update [OPTIONS] [<NIX-FILE>]

  Options:
    -E, --exp <expression>   Pass in a Nix expression that represents the
                              derivation to be updated.
    -s, --save-repo <path>   Specify path to save maven repo to. This will
                              speed up consecutive runs, but might affect
                              lock file if POM is changed in between.
    -n, --no-add             Don't add dependencies to nix store
    -v, --verbose            Verbose output
    -h, --help               Print usage

  Version: $MAVENIX_VERSION
EOF
  exit 1
}

# Setup work dir and cleanup
WORK_DIR=$(mktemp -d --tmpdir mvnix-update.XXXXXX)
cleanup() { { chmod -R +w "$WORK_DIR"; rm -rf "$WORK_DIR"; } || true; }
trap 'trap - EXIT; cleanup; kill -- $$' EXIT

# Default values
tmp_repo="$WORK_DIR/m2-repo"

# Parse CLI arguments
while test "$1";do
  case "$1" in
    -E|--exp) shift;expression="$1";;
    -s|--save-repo) shift;tmp_repo="$1";;
    -n|--no-add) no_add=1;;
    -v|--verbose) verbose=1;set -x;;
    -h|--help) usage;;
    -*) usage "no option \"$1\"";;
    *) config="$1";;
  esac
  shift
done

die() { echo >&2 "$@"; exit 1;}

nix_flags=$(test "$verbose" && printf %s "--verbose" || true)

if [[ "$expression" && "$config" ]]; then
  die "Expression and file arguments are mutually exclusive"
elif [[ "$config" ]]; then
  expression="import \"$(realpath "$config")\" {}"
elif [[ ! "$expression" ]]; then
  expression="import ./. {}"
fi

tmp_repo=$(realpath "$tmp_repo")
mkdir -p "$tmp_repo"

ns_() {
  local ns_wd="$1";shift
  HOME="/tmp/nowhere" nix-shell $nix_flags --show-trace --pure \
    --run "cd \"$ns_wd\"; $*" -E "($expression).overrideAttrs (_: { build = false; })";
}

echo >&2 "
  Getting mavenix meta data...
"

realiseStorePath() {
  # Check if $1 is a store path (similar to lib.isStorePath) and realize only
  # if it is.
  if [[ $1 =~ ^/nix/store/ ]]; then
    nix-store --realise "$1" >/dev/null
  fi
}
mavenixMeta=$(nix-instantiate $nix_flags --eval --strict --json -E "($expression).mavenixMeta" | jq -rc .)
mq() { jq -rc "$1" <<<"$mavenixMeta"; }

test "$mavenixMeta" || die "Nix expression is not a mavenix derivation"

nix-build --no-out-link -E "{ inherit (($expression).mavenixMeta) emptyRepo settings infoFile; }"

src_path=$(mq .srcPath)
realiseStorePath "$src_path"

settings=$(mq .settings)
empty_repo=$(mq .emptyRepo)

if test -d "$empty_repo"; then
  cp -rf -t "$tmp_repo" "$empty_repo"/* >/dev/null 2>&1 || true
  chmod -R u+w "$tmp_repo" || true
fi

src_wd="$src_path"
if test ! -w "$src_wd"; then
  src_wd="$WORK_DIR/src"
  cp -r "$src_path" "$src_wd"
  chmod -R u+w "$src_wd" || true #echo >&2 Failed to set chmod on temp repo dir.
fi

# shellcheck disable=SC2015
mvn_flags=$(test "$verbose" && printf %s "-e -X" || true)
# shellcheck disable=SC2086
mvn_() { ns_ "$src_wd" mvn $mvn_flags -B -nsu --settings "$settings" "$@"; }
mvn_out() { ns_ "$src_wd" mvn -B -nsu --settings "$settings" "$@"; }

echo >&2 "
  Running mvn package...
"
mvn_ >&2 install -Dmaven.test.skip.exec=true -DskipTests -Dmaven.repo.local="$tmp_repo"

echo >&2 "
  Getting project info...
"
pom=$(mvn_out help:effective-pom | grep -v '^\[\|^Effective \|^$' | xq -c .)
projects=$(jq -c '.projects.project // [.project]' <<<"$pom")
pq() { jq -rc "$1" <<<"$projects"; }
export -f pq

groupId=$(pq .[0].groupId)
artifactId=$(pq .[0].artifactId)
version=$(pq .[0].version)

modules=$(pq '
  [ .[]
    | {
      name: (.artifactId + "-" + .version),
      groupId, artifactId, version,
      path: (.build.directory | sub("^'"$src_wd"'/"; "./") | sub("/target"; ""))
    }
  ]
')

remotes_repos=$(pq '
  [ [.[].repositories.repository, .[].pluginRepositories.pluginRepository]
    | flatten | .[]
    | {(.id):.url}
  ] | add
')

tmp_lock_file="$WORK_DIR/tmp-mavenix.lock"
lock_file="$(mq .infoFile)"

echo >&2 "
  Resolving maven dependencies...
"
mvn_ >&2 dependency:go-offline -Dmaven.repo.local="$tmp_repo"

echo >&2 "
  Creating lock file...
"
(
echo -n "{
  \"name\": \"$artifactId-$version\",
  \"groupId\": \"$groupId\",
  \"artifactId\": \"$artifactId\",
  \"version\": \"$version\",
  \"submodules\": $modules,
  \"deps\": [ $(mq .deps[] | sed 's/\(.\)$/\1,/')"
( cd "$tmp_repo"
remotes=$(find . -type f -name "*.repositories" | sed 's|^\./||' | sort)
sep=""
for remote in $remotes; do
  dir=$(dirname "$remote")
  files=$(find "$dir" -type f ! -name "*.repositories" ! -name "*.sha1" \
    | grep -v '^#' "$remote" | sed "s|^|$dir/|" | sort)
  for file_ in $files; do
    file=$(echo "$file_" | cut -d '>' -f1)
    # Maven 3.0.5 for 3.3.9 use $file instead of $file_real
    # shellcheck disable=SC2116,SC2086
    file_real=$(echo ${file//-SNAPSHOT./-[0-9]*.})
    repo=$(echo "$file_" | cut -d '>' -f2 | sed 's/=$//')
    test "$repo" || continue
    echo -n "$sep
    {\"path\":\"$file_real\",\"sha1\":\"$(grep -Eo '[0-9a-zA-Z]{40}' < "$file_real.sha1")\"}"
    sep=","

    test "$no_add" || nix-store --add-fixed sha1 "$file_real" >&2
  done
done

echo -n "
  ],
  \"metas\": ["
metafiles=$(find . -type f -name "maven-metadata-*.xml"  | sed 's|^\./||' | sort)
sep=""
for file in $metafiles; do
  repo=$(basename "$file" | sed 's/^maven-metadata-//;s/\.xml$//')
  [[ "$repo" && "$repo" != "local"  ]] || continue
  echo -n "$sep{
      \"path\": \"$(dirname "$file")\",
      \"content\": \"$(sed ':a;N;$!ba;s/\n/\\n/g;s/\"/\\\"/g' "$file")\"
    }"
  sep=", "
done
)
echo -n "
  ],
  \"remotes\": $remotes_repos
}
"
) > "$tmp_lock_file"

echo >&2 "
  Sanity check...
"
jq -c . "$tmp_lock_file" > /dev/null
jq -S . "$tmp_lock_file" > "$lock_file"

echo >&2 "
  Lock file created at: $lock_file
"


text:
#!/bin/bash
set -e

usage() {
  # shellcheck disable=SC2015
  test "$1" && echo -e Error: "$1"\\n || true
  cat >&2 <<EOF
  Usage: mvnix-init [OPTIONS] [<NIX-FILE>]

  Options:
    -S, --src                A Nix expression to use as 'src' for derivation
    -o, --output <dir>       Output directory for generated files
    -s, --standalone         Include 'mavenix.nix' file
    -f, --force              Overwrite output file if exists
    -v, --verbose            Verbose output
    -h, --help               Print usage

  Version: $MAVENIX_VERSION
EOF
  exit 1
}

tmpl() { sed "s|%%$1%%|$2|g"; }

# Default values
outputDir="."

# Parse CLI arguments
while test "$1";do
  case "$1" in
    -S|--src) shift;srcExpr="($1)";;
    -o|--output) shift;outputDir="$1";;
    -s|--standalone) standalone=1;;
    -f|--force) forceOverwrite=1;;
    -v|--verbose) set -x;;
    -h|--help) usage;;
    -*) usage "no option \"$1\"";;
    *) config="$1";;
  esac
  shift
done

mkdir -p "$outputDir"
config="${config-$outputDir/default.nix}"
[[ -n "$forceOverwrite" || ! -e "$config" ]] || usage "\"$config\" already exists"

srcExpr="${srcExpr-./$(realpath --relative-to="$(dirname "$config")" ".")}"

copy() { cp "$1" "$2"; echo "$2"; }
echo >&2 "
  Creating files:
"

if test "$standalone"; then
  relEnv="./$(realpath --relative-to="$(dirname "$config")" "$outputDir/mavenix.nix")"
  copy "$MAVENIX_SCRIPT" "$outputDir/mavenix.nix"
  chmod u+w "$outputDir/mavenix.nix"
else
  relEnv="fetchTarball { url = \"$MAVENIX_DOWNLOAD\"; sha256 = \"$(nix-prefetch-url "$MAVENIX_DOWNLOAD" --unpack 2>&-)\"; }"
fi

# shellcheck disable=SC2002
cat "$CONFIG_TEMPLATE" \
| tmpl src "$srcExpr" \
| tmpl env "$relEnv" \
> "$config"
echo "$config"

echo >&2 "
  1. Configure by editing '$config'
  2. Create a lock file by running 'mvnix-update \"$config\"'
  3. Build your project 'nix-build \"$config\"'
"


text:
final: prev:
let
  mavenix = import ./. {};
in {
  inherit mavenix;
  mavenix-cli = mavenix.cli;
}


text:
{
  description = "Mavenix";

  inputs.utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, utils }:
    utils.lib.eachSystem utils.lib.allSystems (system:
      let
        pkgs = import nixpkgs { inherit system; };
        mavenix = import ./. { inherit pkgs; };
      in rec {
        packages = utils.lib.flattenTree {
          mavenix-cli = mavenix.cli;
        };
        defaultPackage = packages.mavenix-cli;
        apps.mavenix-cli = utils.lib.mkApp { drv = packages.mavenix-cli; };
        defaultApp = apps.mavenix-cli;
      }) // {
        overlay = final: prev: {
          inherit (import ./mavenix.nix { pkgs = prev; }) buildMaven;
          mavenix-cli = (import ./. { pkgs = prev; }).cli;
        };
      };
}