text:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
  serializedVersion: 6
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: BaseMaterial
  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
  m_ShaderKeywords: _ENVIRONMENTREFLECTIONS_OFF
  m_LightmapFlags: 4
  m_EnableInstancingVariants: 0
  m_DoubleSidedGI: 1
  m_CustomRenderQueue: 2000
  stringTagMap:
    MotionVector: User
    RenderType: Opaque
  disabledShaderPasses:
  - DistortionVectors
  - TransparentDepthPrepass
  - TransparentDepthPostpass
  - TransparentBackface
  - MOTIONVECTORS
  m_SavedProperties:
    serializedVersion: 3
    m_TexEnvs:
    - _AnisotropyMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _BaseColorMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _BaseMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _BentNormalMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _BentNormalMapOS:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _BumpMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _CoatMaskMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _DetailMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _DistortionVectorMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _EmissionMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _EmissiveColorMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _HeightMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _IridescenceMaskMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _IridescenceThicknessMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _MainTex:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _MaskMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _MetallicGlossMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _NormalMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _NormalMapOS:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _OcclusionMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _SpecGlossMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _SpecularColorMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _SubsurfaceMaskMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _TangentMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _TangentMapOS:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _ThicknessMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _TransmittanceColorMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    m_Floats:
    - _AORemapMax: 1
    - _AORemapMin: 0
    - _ATDistance: 1
    - _AlbedoAffectEmissive: 0
    - _AlphaClip: 0
    - _AlphaCutoff: 0.5
    - _AlphaCutoffEnable: 0
    - _AlphaCutoffPostpass: 0.5
    - _AlphaCutoffPrepass: 0.5
    - _AlphaCutoffShadow: 0.5
    - _Anisotropy: 0
    - _Blend: 0
    - _BlendMode: 0
    - _BumpScale: 1
    - _CoatMask: 0
    - _Cull: 0
    - _CullMode: 2
    - _CullModeForward: 2
    - _Cutoff: 0.5
    - _DepthOffsetEnable: 0
    - _DetailAlbedoScale: 1
    - _DetailNormalScale: 1
    - _DetailSmoothnessScale: 1
    - _DiffusionProfile: 0
    - _DisplacementLockObjectScale: 1
    - _DisplacementLockTilingScale: 1
    - _DisplacementMode: 0
    - _DistortionBlendMode: 0
    - _DistortionBlurBlendMode: 0
    - _DistortionBlurDstBlend: 1
    - _DistortionBlurRemapMax: 1
    - _DistortionBlurRemapMin: 0
    - _DistortionBlurScale: 1
    - _DistortionBlurSrcBlend: 1
    - _DistortionDepthTest: 1
    - _DistortionDstBlend: 1
    - _DistortionEnable: 0
    - _DistortionScale: 1
    - _DistortionSrcBlend: 1
    - _DistortionVectorBias: -1
    - _DistortionVectorScale: 2
    - _DoubleSidedEnable: 0
    - _DoubleSidedNormalMode: 1
    - _Drag: 1
    - _DstBlend: 0
    - _EmissiveColorMode: 1
    - _EnableBlendModePreserveSpecularLighting: 1
    - _EnableFogOnTransparent: 1
    - _EnableGeometricSpecularAA: 0
    - _EnableMotionVectorForVertexAnimation: 0
    - _EnableSpecularOcclusion: 0
    - _EnableWind: 0
    - _EnergyConservingSpecularColor: 1
    - _EnvironmentReflections: 0
    - _GlossMapScale: 0
    - _Glossiness: 0
    - _GlossyReflections: 0
    - _HdrpVersion: 2
    - _HeightAmplitude: 0.02
    - _HeightCenter: 0.5
    - _HeightMapParametrization: 0
    - _HeightMax: 1
    - _HeightMin: -1
    - _HeightOffset: 0
    - _HeightPoMAmplitude: 2
    - _HeightTessAmplitude: 2
    - _HeightTessCenter: 0.5
    - _InitialBend: 1
    - _InvTilingScale: 1
    - _Ior: 1
    - _IridescenceMask: 1
    - _IridescenceThickness: 1
    - _LinkDetailsWithBase: 1
    - _MaterialID: 1
    - _Metallic: 0
    - _NormalMapSpace: 0
    - _NormalScale: 1
    - _OcclusionStrength: 1
    - _PPDLodThreshold: 5
    - _PPDMaxSamples: 15
    - _PPDMinSamples: 5
    - _PPDPrimitiveLength: 1
    - _PPDPrimitiveWidth: 1
    - _PreRefractionPass: 0
    - _QueueOffset: 0
    - _ReceiveShadows: 1
    - _ReceivesSSR: 1
    - _RefractionModel: 0
    - _SSRefractionProjectionModel: 0
    - _ShiverDirectionality: 0.5
    - _ShiverDrag: 0.2
    - _Smoothness: 0
    - _SmoothnessRemapMax: 1
    - _SmoothnessRemapMin: 0
    - _SmoothnessTextureChannel: 0
    - _SpecularAAScreenSpaceVariance: 0.1
    - _SpecularAAThreshold: 0.2
    - _SpecularHighlights: 1
    - _SrcBlend: 1
    - _StencilRef: 2
    - _StencilRefMV: 128
    - _StencilWriteMask: 7
    - _StencilWriteMaskMV: 128
    - _Stiffness: 1
    - _SubsurfaceMask: 1
    - _SupportDecals: 1
    - _Surface: 0
    - _SurfaceType: 0
    - _TexWorldScale: 1
    - _TexWorldScaleEmissive: 1
    - _Thickness: 1
    - _ThicknessMultiplier: 1
    - _TransmissionEnable: 1
    - _TransparentBackfaceEnable: 0
    - _TransparentDepthPostpassEnable: 0
    - _TransparentDepthPrepassEnable: 0
    - _TransparentSortPriority: 0
    - _UVBase: 0
    - _UVDetail: 0
    - _UVEmissive: 0
    - _UseShadowThreshold: 0
    - _WorkflowMode: 1
    - _ZTestDepthEqualForOpaque: 3
    - _ZTestGBuffer: 4
    - _ZTestModeDistortion: 4
    - _ZWrite: 1
    m_Colors:
    - _BaseColor: {r: 0.1509434, g: 0.1509434, b: 0.1509434, a: 1}
    - _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0}
    - _Color: {r: 0, g: 0, b: 0, a: 1}
    - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
    - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
    - _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
    - _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
    - _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
    - _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
    - _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
    - _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
    - _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
    - _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}
    - _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0}
--- !u!114 &223293942928947862
MonoBehaviour:
  m_ObjectHideFlags: 11
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 0}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
  m_Name:
  m_EditorClassIdentifier:
  version: 2


text:
fileFormatVersion: 2
guid: 9971d6c963d5a9a44ba7a65e6abda6f9
ModelImporter:
  serializedVersion: 23
  fileIDToRecycleName:
    100000: //RootNode
    400000: //RootNode
    2100000: lambert1
    2300000: //RootNode
    3300000: //RootNode
    4300000: pSphere1
  externalObjects: {}
  materials:
    importMaterials: 1
    materialName: 0
    materialSearch: 1
    materialLocation: 1
  animations:
    legacyGenerateAnimations: 4
    bakeSimulation: 0
    resampleCurves: 1
    optimizeGameObjects: 0
    motionNodeName:
    rigImportErrors:
    rigImportWarnings:
    animationImportErrors:
    animationImportWarnings:
    animationRetargetingWarnings:
    animationDoRetargetingWarnings: 0
    importAnimatedCustomProperties: 0
    importConstraints: 0
    animationCompression: 1
    animationRotationError: 0.5
    animationPositionError: 0.5
    animationScaleError: 0.5
    animationWrapMode: 0
    extraExposedTransformPaths: []
    extraUserProperties: []
    clipAnimations: []
    isReadable: 1
  meshes:
    lODScreenPercentages: []
    globalScale: 1
    meshCompression: 0
    addColliders: 0
    useSRGBMaterialColor: 1
    importVisibility: 1
    importBlendShapes: 1
    importCameras: 1
    importLights: 1
    swapUVChannels: 0
    generateSecondaryUV: 0
    useFileUnits: 1
    optimizeMeshForGPU: 1
    keepQuads: 0
    weldVertices: 1
    preserveHierarchy: 0
    indexFormat: 0
    secondaryUVAngleDistortion: 8
    secondaryUVAreaDistortion: 15.000001
    secondaryUVHardAngle: 88
    secondaryUVPackMargin: 4
    useFileScale: 1
    previousCalculatedGlobalScale: 1
    hasPreviousCalculatedGlobalScale: 0
  tangentSpace:
    normalSmoothAngle: 60
    normalImportMode: 0
    tangentImportMode: 3
    normalCalculationMode: 4
    legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
    blendShapeNormalImportMode: 1
    normalSmoothingSource: 0
  importAnimation: 1
  copyAvatar: 0
  humanDescription:
    serializedVersion: 2
    human: []
    skeleton: []
    armTwist: 0.5
    foreArmTwist: 0.5
    upperLegTwist: 0.5
    legTwist: 0.5
    armStretch: 0.05
    legStretch: 0.05
    feetSpacing: 0
    rootMotionBoneName:
    hasTranslationDoF: 0
    hasExtraRoot: 0
    skeletonHasParents: 1
  lastHumanDescriptionAvatarSource: {instanceID: 0}
  animationType: 0
  humanoidOversampling: 1
  additionalBone: 0
  userData:
  assetBundleName:
  assetBundleVariant:

repo_name: CJT-Jackton/URP-Iridescence-Example

repo_language: HLSL

mime_type: text/plain


text:
fileFormatVersion: 2
guid: d272608f2c433194ea514c15f89acbd2
NativeFormatImporter:
  externalObjects: {}
  mainObjectFileID: 2100000
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 18c41c847b56a274dbec42e65e567a4b
PrefabImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &8608065202623123413
GameObject:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  serializedVersion: 6
  m_Component:
  - component: {fileID: 4506560392912112378}
  m_Layer: 0
  m_Name: UnityBall
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!4 &4506560392912112378
Transform:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 8608065202623123413}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: -3.25, y: 0, z: 1.25}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_Children:
  - {fileID: 6359566245650253884}
  - {fileID: 6043960529903236056}
  m_Father: {fileID: 0}
  m_RootOrder: 0
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &6043960529903102296
PrefabInstance:
  m_ObjectHideFlags: 0
  serializedVersion: 2
  m_Modification:
    m_TransformParent: {fileID: 4506560392912112378}
    m_Modifications:
    - target: {fileID: 100000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_Name
      value: Ball
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalPosition.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalPosition.y
      value: 0.1245
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalPosition.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalRotation.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalRotation.y
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalRotation.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalRotation.w
      value: 1
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_RootOrder
      value: 1
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalEulerAnglesHint.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalEulerAnglesHint.y
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_LocalEulerAnglesHint.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 2300000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_Materials.Array.data[3]
      value:
      objectReference: {fileID: 2100000, guid: d272608f2c433194ea514c15f89acbd2, type: 2}
    - target: {fileID: 2300000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
      propertyPath: m_Materials.Array.data[1]
      value:
      objectReference: {fileID: 2100000, guid: d272608f2c433194ea514c15f89acbd2, type: 2}
    m_RemovedComponents: []
  m_SourcePrefab: {fileID: 100100000, guid: 8ce085e5d05a5e644bc0f3b30926719e, type: 3}
--- !u!4 &6043960529903236056 stripped
Transform:
  m_CorrespondingSourceObject: {fileID: 400000, guid: 8ce085e5d05a5e644bc0f3b30926719e,
    type: 3}
  m_PrefabInstance: {fileID: 6043960529903102296}
  m_PrefabAsset: {fileID: 0}
--- !u!1001 &6359566245650125500
PrefabInstance:
  m_ObjectHideFlags: 0
  serializedVersion: 2
  m_Modification:
    m_TransformParent: {fileID: 4506560392912112378}
    m_Modifications:
    - target: {fileID: 100000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_Name
      value: Base
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalPosition.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalPosition.y
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalPosition.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalRotation.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalRotation.y
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalRotation.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalRotation.w
      value: 1
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_RootOrder
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalEulerAnglesHint.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalEulerAnglesHint.y
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_LocalEulerAnglesHint.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 2300000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
      propertyPath: m_Materials.Array.data[0]
      value:
      objectReference: {fileID: 2100000, guid: d272608f2c433194ea514c15f89acbd2, type: 2}
    m_RemovedComponents: []
  m_SourcePrefab: {fileID: 100100000, guid: fefdc5a337e50954483195d3426846f2, type: 3}
--- !u!4 &6359566245650253884 stripped
Transform:
  m_CorrespondingSourceObject: {fileID: 400000, guid: fefdc5a337e50954483195d3426846f2,
    type: 3}
  m_PrefabInstance: {fileID: 6359566245650125500}
  m_PrefabAsset: {fileID: 0}


text:
fileFormatVersion: 2
guid: 8ce085e5d05a5e644bc0f3b30926719e
ModelImporter:
  serializedVersion: 27
  internalIDToNameTable:
  - first:
      1: 100000
    second: //RootNode
  - first:
      4: 400000
    second: //RootNode
  - first:
      21: 2100000
    second: UnityBall_Body
  - first:
      21: 2100002
    second: UnityBall_Logo
  - first:
      21: 2100004
    second: UnityBall_Sides
  - first:
      21: 2100006
    second: UnityBall_Splits
  - first:
      23: 2300000
    second: //RootNode
  - first:
      33: 3300000
    second: //RootNode
  - first:
      43: 4300000
    second: UnityBall
  externalObjects: {}
  materials:
    importMaterials: 1
    materialName: 0
    materialSearch: 1
    materialLocation: 1
  animations:
    legacyGenerateAnimations: 4
    bakeSimulation: 0
    resampleCurves: 1
    optimizeGameObjects: 0
    motionNodeName:
    rigImportErrors:
    rigImportWarnings:
    animationImportErrors:
    animationImportWarnings:
    animationRetargetingWarnings:
    animationDoRetargetingWarnings: 0
    importAnimatedCustomProperties: 0
    importConstraints: 0
    animationCompression: 1
    animationRotationError: 0.5
    animationPositionError: 0.5
    animationScaleError: 0.5
    animationWrapMode: 0
    extraExposedTransformPaths: []
    extraUserProperties: []
    clipAnimations: []
    isReadable: 1
  meshes:
    lODScreenPercentages: []
    globalScale: 1
    meshCompression: 0
    addColliders: 0
    useSRGBMaterialColor: 1
    sortHierarchyByName: 1
    importVisibility: 1
    importBlendShapes: 1
    importCameras: 1
    importLights: 1
    swapUVChannels: 0
    generateSecondaryUV: 1
    useFileUnits: 1
    keepQuads: 0
    weldVertices: 1
    preserveHierarchy: 0
    skinWeightsMode: 0
    maxBonesPerVertex: 4
    minBoneWeight: 0.001
    meshOptimizationFlags: -1
    indexFormat: 0
    secondaryUVAngleDistortion: 8
    secondaryUVAreaDistortion: 15.000001
    secondaryUVHardAngle: 88
    secondaryUVPackMargin: 4
    useFileScale: 1
  tangentSpace:
    normalSmoothAngle: 60
    normalImportMode: 0
    tangentImportMode: 3
    normalCalculationMode: 4
    legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
    blendShapeNormalImportMode: 1
    normalSmoothingSource: 0
  referencedClips: []
  importAnimation: 1
  humanDescription:
    serializedVersion: 3
    human: []
    skeleton: []
    armTwist: 0.5
    foreArmTwist: 0.5
    upperLegTwist: 0.5
    legTwist: 0.5
    armStretch: 0.05
    legStretch: 0.05
    feetSpacing: 0
    globalScale: 1
    rootMotionBoneName:
    hasTranslationDoF: 0
    hasExtraRoot: 0
    skeletonHasParents: 1
  lastHumanDescriptionAvatarSource: {instanceID: 0}
  animationType: 0
  humanoidOversampling: 1
  avatarSetup: 0
  additionalBone: 0
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: fefdc5a337e50954483195d3426846f2
ModelImporter:
  serializedVersion: 27
  internalIDToNameTable:
  - first:
      1: 100000
    second: //RootNode
  - first:
      4: 400000
    second: //RootNode
  - first:
      21: 2100000
    second: UnityBall_Base
  - first:
      23: 2300000
    second: //RootNode
  - first:
      33: 3300000
    second: //RootNode
  - first:
      43: 4300000
    second: Plane006
  externalObjects: {}
  materials:
    importMaterials: 1
    materialName: 0
    materialSearch: 1
    materialLocation: 1
  animations:
    legacyGenerateAnimations: 4
    bakeSimulation: 0
    resampleCurves: 1
    optimizeGameObjects: 0
    motionNodeName:
    rigImportErrors:
    rigImportWarnings:
    animationImportErrors:
    animationImportWarnings:
    animationRetargetingWarnings:
    animationDoRetargetingWarnings: 0
    importAnimatedCustomProperties: 0
    importConstraints: 0
    animationCompression: 1
    animationRotationError: 0.5
    animationPositionError: 0.5
    animationScaleError: 0.5
    animationWrapMode: 0
    extraExposedTransformPaths: []
    extraUserProperties: []
    clipAnimations: []
    isReadable: 1
  meshes:
    lODScreenPercentages: []
    globalScale: 1
    meshCompression: 0
    addColliders: 0
    useSRGBMaterialColor: 1
    sortHierarchyByName: 1
    importVisibility: 1
    importBlendShapes: 1
    importCameras: 1
    importLights: 1
    swapUVChannels: 0
    generateSecondaryUV: 1
    useFileUnits: 1
    keepQuads: 0
    weldVertices: 1
    preserveHierarchy: 0
    skinWeightsMode: 0
    maxBonesPerVertex: 4
    minBoneWeight: 0.001
    meshOptimizationFlags: -1
    indexFormat: 0
    secondaryUVAngleDistortion: 8
    secondaryUVAreaDistortion: 15.000001
    secondaryUVHardAngle: 88
    secondaryUVPackMargin: 4
    useFileScale: 1
  tangentSpace:
    normalSmoothAngle: 60
    normalImportMode: 0
    tangentImportMode: 3
    normalCalculationMode: 4
    legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
    blendShapeNormalImportMode: 1
    normalSmoothingSource: 0
  referencedClips: []
  importAnimation: 1
  humanDescription:
    serializedVersion: 3
    human: []
    skeleton: []
    armTwist: 0.5
    foreArmTwist: 0.5
    upperLegTwist: 0.5
    legTwist: 0.5
    armStretch: 0.05
    legStretch: 0.05
    feetSpacing: 0
    globalScale: 1
    rootMotionBoneName:
    hasTranslationDoF: 0
    hasExtraRoot: 0
    skeletonHasParents: 1
  lastHumanDescriptionAvatarSource: {instanceID: 0}
  animationType: 0
  humanoidOversampling: 1
  avatarSetup: 0
  additionalBone: 0
  userData:
  assetBundleName:
  assetBundleVariant:


text:
Creative Commons Legal Code

CC0 1.0 Universal

    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
    HEREUNDER.

Statement of Purpose

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

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

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

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

  i. the right to reproduce, adapt, distribute, perform, display,
     communicate, and translate a Work;
 ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
     likeness depicted in a Work;
 iv. rights protecting against unfair competition in regards to a Work,
     subject to the limitations in paragraph 4(a), below;
  v. rights protecting the extraction, dissemination, use and reuse of data
     in a Work;
 vi. database rights (such as those arising under Directive 96/9/EC of the
     European Parliament and of the Council of 11 March 1996 on the legal
     protection of databases, and under any national implementation
     thereof, including any amended or successor version of such
     directive); and
vii. other similar, equivalent or corresponding rights throughout the
     world based on applicable law or treaty, and any national
     implementations thereof.

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

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

4. Limitations and Disclaimers.

 a. No trademark or patent rights held by Affirmer are waived, abandoned,
    surrendered, licensed or otherwise affected by this document.
 b. Affirmer offers the Work as-is and makes no representations or
    warranties of any kind concerning the Work, express, implied,
    statutory or otherwise, including without limitation warranties of
    title, merchantability, fitness for a particular purpose, non
    infringement, or the absence of latent or other defects, accuracy, or
    the present or absence of errors, whether or not discoverable, all to
    the greatest extent permissible under applicable law.
 c. Affirmer disclaims responsibility for clearing rights of other persons
    that may apply to the Work or any use thereof, including without
    limitation any person's Copyright and Related Rights in the Work.
    Further, Affirmer disclaims responsibility for obtaining any necessary
    consents, permissions or other rights required for any use of the
    Work.
 d. Affirmer understands and acknowledges that Creative Commons is not a
    party to this document and has no duty or obligation with respect to
    this CC0 or use of the Work.

repo_name: sindresorhus/swiftlint-config


text:
# swiftlint-config

> Good starter config for [SwiftLint](https://github.com/realm/SwiftLint)

SwiftLint has a lot of [rules](https://github.com/realm/SwiftLint) and it takes time to adjust them to something sensible. You probably don't want exactly what I have, but this should be a good starting point. This is what I use for all [my Swift projects](https://github.com/search?q=user%3Asindresorhus+language%3Aswift).

## Usage

1. Create a `.swiftlint.yml` file in the root of your project with the following:

```
parent_config: https://raw.githubusercontent.com/sindresorhus/swiftlint-config/main/.swiftlint.yml
```

*(Replace `main` with a specific commit hash if you want predictable builds)*

2. Follow the [SwiftLint setup instructions](https://github.com/realm/SwiftLint#installation).

## Badge

Show off that you're using this config.

```
[![sindresorhus's SwiftLint config](https://img.shields.io/badge/SwiftLint-sindresorhus-hotpink.svg)](https://github.com/sindresorhus/swiftlint-config)
```

[![sindresorhus's SwiftLint config](https://img.shields.io/badge/SwiftLint-sindresorhus-hotpink.svg)](https://github.com/sindresorhus/swiftlint-config)


text:
# Awesome V2EX 秘籍

给新手的 V2EX 秘籍。

收录有价值的 [V2EX](https://www.v2ex.com/) 使用指南，攻略等帖子。

欢迎[点赞](https://github.com/v2hot/awesome-v2ex-tips)，[投稿](https://github.com/v2hot/awesome-v2ex-tips/issues)。

## 列表

- [`[/t/930514]` 油猴脚本“V2EX - 超级增强”：体验更现代化的 V2EX！](https://www.v2ex.com/t/930514)

- [`[/t/930155]` ✨ V2EX 超强浏览器扩展：体验更先进的 V2EX！](https://www.v2ex.com/t/930155)

- [`[/t/924103]` 🏷 开源一个提升摸鱼乐趣的油猴脚本/浏览器扩展 - 小鱼标签（UTags）](https://www.v2ex.com/t/924103)

- **滥用 AI 回复会被 ban**

  - [`[/t/925818]` GPT 生成的内容确实需要 Ban](https://www.v2ex.com/t/925818)
  - [`[/t/900131]` 请问有没有办法在 V2EX 屏蔽 chatGPT 回复？](https://www.v2ex.com/t/900131)

- [`[/t/895946]` 我写了一个 V2EX 图片灯箱油猴插件](https://www.v2ex.com/t/895946)

- [`[/t/825679]` block 过于激烈？ red 过于刺眼？要不试试 tag](https://www.v2ex.com/t/825679)

- [`[/t/883252]` V2exOS - 用 SwiftUI 写了一个 V2EX 客户端](https://www.v2ex.com/t/883252)

- [`[/t/851399]` 分享一款自用的 V2EX 仿微信风格 CSS](https://www.v2ex.com/t/851399)

  - [https://github.com/CrazyMelody/v2ex_style](https://github.com/CrazyMelody/v2ex_style)

- [`[/t/848726]` 写了个油猴脚本让 V2EX 拥有 SPA 单页的无刷新类似路由切换页面的 Feel](https://www.v2ex.com/t/848726)

- **图片上传**

  - [`[/t/937487]` 🙏🏻 拜托各位发帖如果使用 imgur，在链接后面加上图片格式](https://www.v2ex.com/t/937487)
  - [`[/t/846267]` [必学] V2EX 发布图文帖子的方法](https://www.v2ex.com/t/846267)
  - [`[/t/601213]` v2ex 图片上传终极解决方法](https://www.v2ex.com/t/601213)
  - [`[/t/408727]` 攻略：教你如何在 V2EX 发图片/插链接/插代码/插视频（第二版）](https://www.v2ex.com/t/408727)
  - [`[/t/332852]` 今天让我以最简单明了的方式教你如何在 V2EX 贴图片，毕竟总是有新人不会](https://www.v2ex.com/t/332852)

- [`[/t/822425]` v2ex 主题样式版本更新，支持亮色与暗色 🌙☀，支持自定义背景。](https://www.v2ex.com/t/822425)

  - [https://github.com/viewweiwu/v2ex-zhihu-theme](https://github.com/viewweiwu/v2ex-zhihu-theme)

- [`[/t/822020]` 分享一个能看每天 V2EX 最热的网站，又一个 V2HOT 来了](https://www.v2ex.com/t/822020)

  - [https://github.com/v2hot/v2hot-about](https://github.com/v2hot/v2hot-about)

- **客户端**

  - [`[/t/820329]` 想买一个 iOS 的 V2EX 客户端，哪个好？](https://www.v2ex.com/t/820329)
  - [`[/t/767051]` v2ex 有没有安卓客户端](https://www.v2ex.com/t/767051)
  - [`[/t/434884]` v2ex 有什么好用的三方客户端？](https://www.v2ex.com/t/434884)

- [`[/t/293527]` 关于 V2EX 支持的两种发贴语法的区别](https://www.v2ex.com/t/293527)

- [`[/t/919083]` V2EX Plus 扩展升级到 2.0 版本了](https://www.v2ex.com/t/919083)

  - [`[/t/267300]` V2EX plus 扩展要迁移项目地址并升级到 1.0 版啦！](https://www.v2ex.com/t/267300)
  - [`[/t/198074]` 可能是 V2EX 最好用的插件](https://www.v2ex.com/t/198074)
  - [https://github.com/sciooga/v2ex-plus](https://github.com/sciooga/v2ex-plus)

- [`[/t/561180]` V2EX 不是网络暴力的容器](https://www.v2ex.com/t/561180)

- **修改密码**

  - [`[/t/389088]` 通过 google 登录的方式怎么修改 V2EX 的密码](https://www.v2ex.com/t/389088)
  - [`[/t/790845]` 通过谷歌账号注册的用户如何更改密码？](https://www.v2ex.com/t/790845)

- [`[/t/130362]` 强烈推荐 V2EX 增加删除自己回复或者帖子的功能](https://www.v2ex.com/t/130362)

- [`[/t/99225]` 关于在 V2EX 过滤信息的几种方式](https://www.v2ex.com/t/99225)

- [`[/t/26329]` TIP - 对话守则](https://www.v2ex.com/t/26329)

- [`[/t/10706]` TIP - V2EX 不欢迎全文转载其他地方的文章](https://www.v2ex.com/t/10706)

- [`[/t/10686]` TIP - 提问指南](https://www.v2ex.com/t/10686)

- [`[/t/10553]` FAQ - DEACTIVATE](https://www.v2ex.com/t/10553)

- [About V2EX](https://www.v2ex.com/about)

## 🔥 V2HOT - 每日 V2EX 最热主题 🔥

V2HOT 是可以免费查看每日 V2EX 最热主题历史记录的网站。

欢迎[点赞](https://github.com/v2hot/v2hot-about)，收藏。

GitHub: <https://github.com/v2hot/v2hot.github.io> (已不能访问)

可以通过下列域名访问，选择访问最快的域名。

- <https://v2hot.pipecraft.net/>
- <https://v2exhot.web.app/>
- <https://v2hot.now.sh/>
- <https://v2hot.vercel.app/>
- <https://v2exhot.now.sh/>
- <https://v2exhot.vercel.app/>
- <https://v2hot.github.io/> (已不能访问)

## 🏷 小鱼标签 (UTags) - 为链接添加用户标签

此插件允许用户为网站的链接添加自定义标签。比如，可以给论坛的用户、帖子、节点添加标签。支持 [www.v2ex.com](https://www.v2ex.com/)。陆续会支持更多网站。

**UTags** = **Usertags**。**Userscript**, **Userstyle** 可以让用户自定义网站的功能和样式，**Usertags** 允许用户自定义网站的标签。

### 安装

- 油猴脚本: [https://greasyfork.org/scripts/460718-utags-add-usertags-to-links](https://greasyfork.org/scripts/460718-utags-add-usertags-to-links)

更多内容请访问 [https://github.com/utags/utags](https://github.com/utags/utags)

## v2ex.min - V2EX 极简风格

V2EX 极简风格，简洁风格，扁平化 UI，导航栏顶部固定，快捷按钮，去除背景图片，支持黑暗模式，去除广告，去除不必要元素，支持隐藏头像，支持自定义样式。

### 安装

- 油猴脚本: [https://greasyfork.org/scripts/463552-v2ex-min](https://greasyfork.org/scripts/463552-v2ex-min)

更多内容请访问 [https://github.com/v2hot/v2ex.min](https://github.com/v2hot/v2ex.min)

## 🔧 好工具周刊 📩

发现并分享有趣，有创意，免费、好用的工具，每周四发布。支持 RSS 订阅，邮箱订阅，微信订阅。

好工具周刊同时发布到三个平台，订阅方式提供多种选择。

- [BestXTools 社区（RSS）](https://discuss-cn.bestxtools.com/t/weekly)
- [GitHub（Watch）](https://github.com/bestxtools/weekly-cn)
- [竹白（邮箱，微信）](https://bestxtools.zhubai.love/)

欢迎交流，[投稿](https://discuss-cn.bestxtools.com/d/8)，订阅。

## 🧑🏻💻 DTO - Dev Topics Only

**[DTO](https://dto.pipecraft.net/)** 是一个只讨论技术话题的程序员社区。它是一个类似 [Hacker News](https://news.ycombinator.com/), [Lobsters](https://lobste.rs/) 的链接分享社区，在这里只可以分享与程序开发相关的链接与内容。

[https://dto.pipecraft.net/](https://dto.pipecraft.net/)

## License

Copyright (c) 2022 [Pipecraft](https://www.pipecraft.net). Licensed under the [CC0-1.0 License](https://github.com/bestxtools/weekly-cn/blob/main/LICENSE).

## >\_

[![Pipecraft](https://img.shields.io/badge/site-pipecraft-brightgreen)](https://www.pipecraft.net)
[![V2HOT](https://img.shields.io/badge/site-V2HOT-brightgreen)](https://v2hot.pipecraft.net)
[![UTags](https://img.shields.io/badge/site-UTags-brightgreen)](https://utags.pipecraft.net)
[![BestXTools](https://img.shields.io/badge/site-bestxtools-brightgreen)](https://www.bestxtools.com)
[![DTO](https://img.shields.io/badge/site-DTO-brightgreen)](https://dto.pipecraft.net)


text:
include REQUIREMENTS
include distribute_setup.py

repo_name: zacharyvoase/django-boss

repo_language: Python


text:
#!python
"""Bootstrap distribute installation

If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::

    from distribute_setup import use_setuptools
    use_setuptools()

If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.

This file can also be run as a script to install or upgrade setuptools.
"""
import os
import sys
import time
import fnmatch
import tempfile
import tarfile
from distutils import log

try:
    from site import USER_SITE
except ImportError:
    USER_SITE = None

try:
    import subprocess

    def _python_cmd(*args):
        args = (sys.executable,) + args
        return subprocess.call(args) == 0

except ImportError:
    # will be used for python 2.3
    def _python_cmd(*args):
        args = (sys.executable,) + args
        # quoting arguments if windows
        if sys.platform == 'win32':
            def quote(arg):
                if ' ' in arg:
                    return '"%s"' % arg
                return arg
            args = [quote(arg) for arg in args]
        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0

DEFAULT_VERSION = "0.6.10"
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
SETUPTOOLS_FAKED_VERSION = "0.6c11"

SETUPTOOLS_PKG_INFO = """\
Metadata-Version: 1.0
Name: setuptools
Version: %s
Summary: xxxx
Home-page: xxx
Author: xxx
Author-email: xxx
License: xxx
Description: xxx
""" % SETUPTOOLS_FAKED_VERSION

def _install(tarball):
    # extracting the tarball
    tmpdir = tempfile.mkdtemp()
    log.warn('Extracting in %s', tmpdir)
    old_wd = os.getcwd()
    try:
        os.chdir(tmpdir)
        tar = tarfile.open(tarball)
        _extractall(tar)
        tar.close()

        # going in the directory
        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
        os.chdir(subdir)
        log.warn('Now working in %s', subdir)

        # installing
        log.warn('Installing Distribute')
        if not _python_cmd('setup.py', 'install'):
            log.warn('Something went wrong during the installation.')
            log.warn('See the error message above.')
    finally:
        os.chdir(old_wd)

def _build_egg(egg, tarball, to_dir):
    # extracting the tarball
    tmpdir = tempfile.mkdtemp()
    log.warn('Extracting in %s', tmpdir)
    old_wd = os.getcwd()
    try:
        os.chdir(tmpdir)
        tar = tarfile.open(tarball)
        _extractall(tar)
        tar.close()

        # going in the directory
        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
        os.chdir(subdir)
        log.warn('Now working in %s', subdir)

        # building an egg
        log.warn('Building a Distribute egg in %s', to_dir)
        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)

    finally:
        os.chdir(old_wd)
    # returning the result
    log.warn(egg)
    if not os.path.exists(egg):
        raise IOError('Could not build the egg.')

def _do_download(version, download_base, to_dir, download_delay):
    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
                       % (version, sys.version_info[0], sys.version_info[1]))
    if not os.path.exists(egg):
        tarball = download_setuptools(version, download_base,
                                      to_dir, download_delay)
        _build_egg(egg, tarball, to_dir)
    sys.path.insert(0, egg)
    import setuptools
    setuptools.bootstrap_install_from = egg

def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
                   to_dir=os.curdir, download_delay=15, no_fake=True):
    # making sure we use the absolute path
    to_dir = os.path.abspath(to_dir)
    was_imported = 'pkg_resources' in sys.modules or \
        'setuptools' in sys.modules
    try:
        try:
            import pkg_resources
            if not hasattr(pkg_resources, '_distribute'):
                if not no_fake:
                    _fake_setuptools()
                raise ImportError
        except ImportError:
            return _do_download(version, download_base, to_dir, download_delay)
        try:
            pkg_resources.require("distribute>="+version)
            return
        except pkg_resources.VersionConflict:
            e = sys.exc_info()[1]
            if was_imported:
                sys.stderr.write(
                "The required version of distribute (>=%s) is not available,\n"
                "and can't be installed while this script is running. Please\n"
                "install a more recent version first, using\n"
                "'easy_install -U distribute'."
                "\n\n(Currently using %r)\n" % (version, e.args[0]))
                sys.exit(2)
            else:
                del pkg_resources, sys.modules['pkg_resources']    # reload ok
                return _do_download(version, download_base, to_dir,
                                    download_delay)
        except pkg_resources.DistributionNotFound:
            return _do_download(version, download_base, to_dir,
                                download_delay)
    finally:
        if not no_fake:
            _create_fake_setuptools_pkg_info(to_dir)

def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
                        to_dir=os.curdir, delay=15):
    """Download distribute from a specified location and return its filename

    `version` should be a valid distribute version number that is available
    as an egg for download under the `download_base` URL (which should end
    with a '/'). `to_dir` is the directory where the egg will be downloaded.
    `delay` is the number of seconds to pause before an actual download
    attempt.
    """
    # making sure we use the absolute path
    to_dir = os.path.abspath(to_dir)
    try:
        from urllib.request import urlopen
    except ImportError:
        from urllib2 import urlopen
    tgz_name = "distribute-%s.tar.gz" % version
    url = download_base + tgz_name
    saveto = os.path.join(to_dir, tgz_name)
    src = dst = None
    if not os.path.exists(saveto):  # Avoid repeated downloads
        try:
            log.warn("Downloading %s", url)
            src = urlopen(url)
            # Read/write all in one block, so we don't create a corrupt file
            # if the download is interrupted.
            data = src.read()
            dst = open(saveto, "wb")
            dst.write(data)
        finally:
            if src:
                src.close()
            if dst:
                dst.close()
    return os.path.realpath(saveto)

def _patch_file(path, content):
    """Will backup the file then patch it"""
    existing_content = open(path).read()
    if existing_content == content:
        # already patched
        log.warn('Already patched.')
        return False
    log.warn('Patching...')
    _rename_path(path)
    f = open(path, 'w')
    try:
        f.write(content)
    finally:
        f.close()
    return True

def _same_content(path, content):
    return open(path).read() == content

def _no_sandbox(function):
    def __no_sandbox(*args, **kw):
        try:
            from setuptools.sandbox import DirectorySandbox
            def violation(*args):
                pass
            DirectorySandbox._old = DirectorySandbox._violation
            DirectorySandbox._violation = violation
            patched = True
        except ImportError:
            patched = False

        try:
            return function(*args, **kw)
        finally:
            if patched:
                DirectorySandbox._violation = DirectorySandbox._old
                del DirectorySandbox._old

    return __no_sandbox

@_no_sandbox
def _rename_path(path):
    new_name = path + '.OLD.%s' % time.time()
    log.warn('Renaming %s into %s', path, new_name)
    os.rename(path, new_name)
    return new_name

def _remove_flat_installation(placeholder):
    if not os.path.isdir(placeholder):
        log.warn('Unkown installation at %s', placeholder)
        return False
    found = False
    for file in os.listdir(placeholder):
        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
            found = True
            break
    if not found:
        log.warn('Could not locate setuptools*.egg-info')
        return

    log.warn('Removing elements out of the way...')
    pkg_info = os.path.join(placeholder, file)
    if os.path.isdir(pkg_info):
        patched = _patch_egg_dir(pkg_info)
    else:
        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)

    if not patched:
        log.warn('%s already patched.', pkg_info)
        return False
    # now let's move the files out of the way
    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
        element = os.path.join(placeholder, element)
        if os.path.exists(element):
            _rename_path(element)
        else:
            log.warn('Could not find the %s element of the '
                     'Setuptools distribution', element)
    return True

def _after_install(dist):
    log.warn('After install bootstrap.')
    placeholder = dist.get_command_obj('install').install_purelib
    _create_fake_setuptools_pkg_info(placeholder)

@_no_sandbox
def _create_fake_setuptools_pkg_info(placeholder):
    if not placeholder or not os.path.exists(placeholder):
        log.warn('Could not find the install location')
        return
    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
            (SETUPTOOLS_FAKED_VERSION, pyver)
    pkg_info = os.path.join(placeholder, setuptools_file)
    if os.path.exists(pkg_info):
        log.warn('%s already exists', pkg_info)
        return

    log.warn('Creating %s', pkg_info)
    f = open(pkg_info, 'w')
    try:
        f.write(SETUPTOOLS_PKG_INFO)
    finally:
        f.close()

    pth_file = os.path.join(placeholder, 'setuptools.pth')
    log.warn('Creating %s', pth_file)
    f = open(pth_file, 'w')
    try:
        f.write(os.path.join(os.curdir, setuptools_file))
    finally:
        f.close()

def _patch_egg_dir(path):
    # let's check if it's already patched
    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
    if os.path.exists(pkg_info):
        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
            log.warn('%s already patched.', pkg_info)
            return False
    _rename_path(path)
    os.mkdir(path)
    os.mkdir(os.path.join(path, 'EGG-INFO'))
    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
    f = open(pkg_info, 'w')
    try:
        f.write(SETUPTOOLS_PKG_INFO)
    finally:
        f.close()
    return True

def _before_install():
    log.warn('Before install bootstrap.')
    _fake_setuptools()

def _under_prefix(location):
    if 'install' not in sys.argv:
        return True
    args = sys.argv[sys.argv.index('install')+1:]
    for index, arg in enumerate(args):
        for option in ('--root', '--prefix'):
            if arg.startswith('%s=' % option):
                top_dir = arg.split('root=')[-1]
                return location.startswith(top_dir)
            elif arg == option:
                if len(args) > index:
                    top_dir = args[index+1]
                    return location.startswith(top_dir)
            elif option == '--user' and USER_SITE is not None:
                return location.startswith(USER_SITE)
    return True

def _fake_setuptools():
    log.warn('Scanning installed packages')
    try:
        import pkg_resources
    except ImportError:
        # we're cool
        log.warn('Setuptools or Distribute does not seem to be installed.')
        return
    ws = pkg_resources.working_set
    try:
        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
                                  replacement=False))
    except TypeError:
        # old distribute API
        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))

    if setuptools_dist is None:
        log.warn('No setuptools distribution found')
        return
    # detecting if it was already faked
    setuptools_location = setuptools_dist.location
    log.warn('Setuptools installation detected at %s', setuptools_location)

    # if --root or --preix was provided, and if
    # setuptools is not located in them, we don't patch it
    if not _under_prefix(setuptools_location):
        log.warn('Not patching, --root or --prefix is installing Distribute'
                 ' in another location')
        return

    # let's see if its an egg
    if not setuptools_location.endswith('.egg'):
        log.warn('Non-egg installation')
        res = _remove_flat_installation(setuptools_location)
        if not res:
            return
    else:
        log.warn('Egg installation')
        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
        if (os.path.exists(pkg_info) and
            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
            log.warn('Already patched.')
            return
        log.warn('Patching...')
        # let's create a fake egg replacing setuptools one
        res = _patch_egg_dir(setuptools_location)
        if not res:
            return
    log.warn('Patched done.')
    _relaunch()

def _relaunch():
    log.warn('Relaunching...')
    # we have to relaunch the process
    args = [sys.executable] + sys.argv
    sys.exit(subprocess.call(args))

def _extractall(self, path=".", members=None):
    """Extract all members from the archive to the current working
       directory and set owner, modification time and permissions on
       directories afterwards. `path' specifies a different directory
       to extract to. `members' is optional and must be a subset of the
       list returned by getmembers().
    """
    import copy
    import operator
    from tarfile import ExtractError
    directories = []

    if members is None:
        members = self

    for tarinfo in members:
        if tarinfo.isdir():
            # Extract directories with a safe mode.
            directories.append(tarinfo)
            tarinfo = copy.copy(tarinfo)
            tarinfo.mode = 448 # decimal for oct 0700
        self.extract(tarinfo, path)

    # Reverse sort directories.
    if sys.version_info < (2, 4):
        def sorter(dir1, dir2):
            return cmp(dir1.name, dir2.name)
        directories.sort(sorter)
        directories.reverse()
    else:
        directories.sort(key=operator.attrgetter('name'), reverse=True)

    # Set correct owner, mtime and filemode on directories.
    for tarinfo in directories:
        dirpath = os.path.join(path, tarinfo.name)
        try:
            self.chown(tarinfo, dirpath)
            self.utime(tarinfo, dirpath)
            self.chmod(tarinfo, dirpath)
        except ExtractError:
            e = sys.exc_info()[1]
            if self.errorlevel > 1:
                raise
            else:
                self._dbg(1, "tarfile: %s" % e)

def main(argv, version=DEFAULT_VERSION):
    """Install or upgrade setuptools and EasyInstall"""
    tarball = download_setuptools()
    _install(tarball)

if __name__ == '__main__':
    main(sys.argv[1:])


text:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import re

from distribute_setup import use_setuptools; use_setuptools()
from setuptools import setup, find_packages

rel_file = lambda *args: os.path.join(os.path.dirname(os.path.abspath(__file__)), *args)

def read_from(filename):
    fp = open(filename)
    try:
        return fp.read()
    finally:
        fp.close()

def get_version():
    data = read_from(rel_file('src', 'djboss', '__init__.py'))
    return re.search(r"__version__ = '([^']+)'", data).group(1)

def get_requirements():
    data = read_from(rel_file('REQUIREMENTS'))
    lines = map(lambda s: s.strip(), data.splitlines())
    return filter(None, lines)

setup(
    name             = 'django-boss',
    version          = get_version(),
    author           = "Zachary Voase",
    author_email     = "zacharyvoase@me.com",
    url              = 'http://github.com/zacharyvoase/django-boss',
    description      = "Django management commands, revisited.",
    packages         = find_packages(where='src'),
    package_dir      = {'': 'src'},
    entry_points     = {'console_scripts': ['djboss = djboss.cli:main']},
    install_requires = get_requirements(),
)


text:
# `django-boss`

`django-boss` is an implementation of the ideas outlined in [my blog post][0] on
Django management commands. With `django-boss`, you can specify commands in
individual apps and then run them using the `djboss` command-line interface.

  [0]: http://blog.zacharyvoase.com/2009/12/09/django-boss/

## News

#### 0.6.1

If `settings.DEBUG` is `True`, the default logging level will be set to `DEBUG`.
Otherwise it will be `WARN`.

### 0.6

`django-boss` is now free and unencumbered software released into the public
domain.

### 0.5

You can now use the `MODEL_LABEL` argparse type to define arguments which take
model specifiers. The arguments object will contain the model class. For
example:

    from djboss.commands import *

    @command
    @argument('model', type=MODEL_LABEL)
    def print_model(args):
        """Print the class object for a specified model."""
        print args.model

Could be run like this:

    $ djboss print-model auth.user
    <class 'django.contrib.auth.User'>

Model specifiers take the form `app_label.model_name`, where `model_name` is
case-insensitive.

### 0.4

You can now use the `APP_LABEL` argparse type to define an argument which takes
the name of an installed Django app; the attribute on the arguments object will
hold the appropriate module object. For example, this:

    from djboss.commands import *

    @command
    @argument('app', type=APP_LABEL)
    def print_app(args):
        """Print the module object for a specified app."""
        print args.app

Would run like this:

    $ djboss print-app auth
    <module 'django.contrib.auth' from '/.../auth/__init__.pyc'>

### 0.2

`django-boss` now comes with a `manage` command that lets you run *native*
Django management commands under `djboss`. For example:

    $ djboss manage --help
    $ djboss manage syncdb
    $ djboss manage runserver --help

So you can (if you want) delete the `./manage.py` file in your project and use
`djboss` exclusively!

## Installing `django-boss`

At the moment, installation is done via `easy_install django-boss` or
`pip install django-boss`. The only prerequisites are
[argparse](http://argparse.googlecode.com), whose installation is handled by
setuptools, and [Django](http://djangoproject.com/), which you should have
installed by now anyway.

## Writing Commands

Commands are defined as instances of `djboss.commands.Command`, present in a
`commands` submodule inside an installed app. For example, take the following
app layout:

    echoapp/
    |-- __init__.py
    |-- commands.py
    `-- models.py

The `commands.py` file is a submodule that can be imported as
`echoapp.commands`.

### With Decorators

The following is a complete example of a valid `commands.py` file:

    from djboss.commands import *

    @command
    def hello(args):
        """Print a cliche to the console."""

        print "Hello, World!"

This example uses the `@command` decorator to declare that the function is a
`django-boss` command. You can add arguments to commands too; just use the
`@argument` decorator (make sure they come *after* the `@command`):

    @command
    @argument('-n', '--no-newline', action='store_true',
              help="Don't append a trailing newline.")
    def hello(args):
        """Print a cliche to the console."""

        if args.no_newline:
            import sys
            sys.stdout.write("Hello, World!")
        else:
            print "Hello, World!"

The `@argument` decorator accepts whatever
`argparse.ArgumentParser.add_argument()` does; consult the [argparse docs][1]
for more information.

  [1]: http://argparse.googlecode.com/svn/tags/r101/doc/add_argument.html

You can also annotate commands by giving keyword arguments to `@command`:

    @command(name="something", description="Does something.")
    def do_something(args):
        """Do something."""

        print "something has been done."

In this case, the command will be called `"something"` instead of the
auto-generated `"do-something"`, and its description will differ from its
docstring. For more information on what can be passed in here, consult the
[argparse.ArgumentParser docs][2].

  [2]: http://argparse.googlecode.com/svn/tags/r101/doc/ArgumentParser.html

### Without Decorators

The API is very similar without decorators. The `Command` class is used to wrap
functions, and you can give keyword arguments when invoking it as with
`@command`:

    def echo(args):
        ...
    echo = Command(echo, name='...', description='...')

Adding arguments uses the `Command.add_argument()` method, which is just a
reference to the generated sub-parser’s `add_argument()` method:

    def echo(args):
        ...
    echo = Command(echo, name='...', description='...')
    echo.add_argument('-n', '--no-newline', ...)
    echo.add_argument('words', nargs='*')

## Running Commands

Commands are executed via the `djboss` command-line interface. For this to run
correctly, you need one of two things:

*   A `DJANGO_SETTINGS_MODULE` environment variable which refers to a valid,
    importable Python module.
*   A valid, importable `settings` module in the current working directory.

Once one of those is covered, you can run it:

    $ djboss --help
    usage: djboss [-h] [-v] [-l LEVEL] COMMAND ...

    Run django-boss management commands.

    optional arguments:
      -h, --help            show this help message and exit
      -v, --version         show program's version number and exit
      -l LEVEL, --log-level LEVEL
                            Choose a log level from DEBUG, INFO, WARN (default)
                            or ERROR.

    commands:
      COMMAND
        echo                Echo the arguments back to the console.
        hello               Print a cliche to the console.

    To discover sub-commands, djboss first finds and imports your Django settings.
    The DJANGO_SETTINGS_MODULE environment variable takes precedence, but if
    unspecified, djboss will look for a `settings` module in the current
    directory. Commands should be defined in a `commands` submodule of each app.
    djboss will search each of your INSTALLED_APPS for management commands.

Each subcommand gets a `--help` option too:

    $ djboss echo --help
    usage: djboss echo [-h] [-n] [words [words ...]]

    Echo the arguments back to the console.

    positional arguments:
      words

    optional arguments:
      -h, --help        show this help message and exit
      -n, --no-newline  Don't print a newline afterwards.

And then you can run it:

    $ djboss echo some words here
    some words here

More of the same:

    $ djboss hello --help
    usage: djboss hello [-h]

    Print a cliche to the console.

    optional arguments:
      -h, --help  show this help message and exit

And finally:

    $ djboss hello
    Hello, World!

## (Un)license

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.

In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org/>


text:
# -*- coding: utf-8 -*-

import argparse

import djboss

PARSER = argparse.ArgumentParser(
    prog = 'djboss',
    description = "Run django-boss management commands.",
    epilog = """
    To discover sub-commands, djboss first finds and imports your Django
    settings. The DJANGO_SETTINGS_MODULE environment variable takes precedence,
    but if unspecified, djboss will look for a `settings` module in the current
    directory.

    Commands should be defined in a `commands` submodule of each app. djboss
    will search each of your INSTALLED_APPS for management commands.""",
)

PARSER.add_argument('--version', action='version', version=djboss.__version__)

PARSER.add_argument('-l', '--log-level', metavar='LEVEL',
    default='WARN', choices='DEBUG INFO WARN ERROR'.split(),
    help="Choose a log level from DEBUG, INFO, WARN or ERROR "
         "(default: %(default)s)")

SUBPARSERS = PARSER.add_subparsers(dest='command', title='commands', metavar='COMMAND')


text:
# -*- coding: utf-8 -*-

__version__ = '0.6.3'


text:
# -*- coding: utf-8 -*-

import logging
import os
import sys
import textwrap

from django.utils.importlib import import_module

from djboss.commands import Command

class SettingsImportError(ImportError):
    pass

def get_settings():
    sys.path.append(os.getcwd())
    if 'DJANGO_SETTINGS_MODULE' in os.environ:
        try:
            return import_module(os.environ['DJANGO_SETTINGS_MODULE'])
        except ImportError, exc:
            raise SettingsImportError(textwrap.dedent("""\
                There was an error importing the module specified by the
                DJANGO_SETTINGS_MODULE environment variable. Make sure that it
                refers to a valid and importable Python module."""), exc)

    try:
        import settings
    except ImportError, exc:
        raise SettingsImportError(textwrap.dedent("""\
            Couldn't import a settings module. Make sure that a `settings.py`
            file exists in the current directory, and that it can be imported,
            or that the DJANGO_SETTINGS_MODULE environment variable points
            to a valid and importable Python module."""), exc)
    return settings

def find_commands(app):
    """Return a dict of `command_name: command_obj` for the given app."""

    commands = {}
    app_module = import_module(app) # Fail loudly if an app doesn't exist.
    try:
        commands_module = import_module(app + '.commands')
    except ImportError:
        pass
    else:
        for command in vars(commands_module).itervalues():
            if isinstance(command, Command):
                commands[command.name] = command
    return commands

def find_all_commands(apps):
    """Return a dict of `command_name: command_obj` for all the given apps."""

    commands = {}
    commands.update(find_commands('djboss'))
    for app in apps:
        commands.update(find_commands(app))
    return commands

def main():
    try:
        settings = get_settings()
    except SettingsImportError, exc:
        print >> sys.stderr, exc.args[0]
        print >> sys.stderr
        print >> sys.stderr, "The original exception was:"
        print >> sys.stderr, '\t' + str(exc.args[1])
        sys.exit(1)

    from django.core import management as mgmt
    mgmt.setup_environ(settings)

    commands = find_all_commands(settings.INSTALLED_APPS)

    from djboss.parser import PARSER

    PARSER.set_defaults(settings=settings)
    if settings.DEBUG:
        PARSER.set_defaults(log_level='DEBUG')
    else:
        PARSER.set_defaults(log_level='WARN')

    args = PARSER.parse_args()
    logging.root.setLevel(getattr(logging, args.log_level))

    # Call the command.
    commands[args.command](args)

if __name__ == '__main__':
    main()


text:
# -*- coding: utf-8 -*-

import functools
import re
import sys

from djboss.parser import SUBPARSERS

__all__ = ['Command', 'command', 'argument', 'APP_LABEL', 'MODEL_LABEL']

class Command(object):

    """Wrapper to manage creation and population of sub-parsers on functions."""

    def __init__(self, function, **kwargs):
        self.function = function
        self.parser = self._make_parser(**kwargs)
        self._init_arguments()

    add_argument = property(lambda self: self.parser.add_argument)

    def __call__(self, args):
        return self.function(args)

    def name(self):
        """The name of this command."""

        if hasattr(self.function, 'djboss_name'):
            return self.function.djboss_name
        else:
            return self.function.__name__.replace('_', '-')
    name = property(name)

    def help(self):
        if hasattr(self.function, 'djboss_help'):
            return self.function.djboss_help
        elif getattr(self.function, '__doc__', None):
            # Just the first line of the docstring.
            return self.function.__doc__.splitlines()[0]
    help = property(help)

    def description(self):
        if hasattr(self.function, 'djboss_description'):
            return self.function.djboss_description
        elif getattr(self.function, '__doc__', None):
            return self.function.__doc__
    description = property(description)

    def _make_parser(self, **kwargs):
        """Create and register a subparser for this command."""

        kwargs.setdefault('help', self.help)
        kwargs.setdefault('description', self.description)
        return SUBPARSERS.add_parser(self.name, **kwargs)

    def _init_arguments(self):
        """Initialize the subparser with arguments stored on the function."""

        if hasattr(self.function, 'djboss_arguments'):
            while self.function.djboss_arguments:
                args, kwargs = self.function.djboss_arguments.pop()
                self.add_argument(*args, **kwargs)

def APP_LABEL(label=None, **kwargs):

    """
    argparse type to resolve arguments to Django apps.

    Example Usage:

    *   `@argument('app', type=APP_LABEL)`
    *   `@argument('app', type=APP_LABEL(empty=False))`
    *   `APP_LABEL('auth')` => `<module 'django.contrib.auth' ...>`
    """

    from django.db import models
    from django.conf import settings
    from django.utils.importlib import import_module

    if label is None:
        return functools.partial(APP_LABEL, **kwargs)

    # `get_app('auth')` will return the `django.contrib.auth.models` module.
    models_module = models.get_app(label, emptyOK=kwargs.get('empty', True))
    if models_module is None:
        for installed_app in settings.INSTALLED_APPS:
            # 'app' should resolve to 'path.to.app'.
            if installed_app.split('.')[-1] == label:
                return import_module(installed_app)
    else:
        # 'path.to.app.models' => 'path.to.app'
        return import_module(models_module.__name__.rsplit('.', 1)[0])

def MODEL_LABEL(label):

    """
    argparse type to resolve arguments to Django models.

    Example Usage:

    *   `@argument('app.model', type=MODEL_LABEL)
    *   `MODEL_LABEL('auth.user')` => `<class 'django.contrib.auth.models.User'>`
    """

    from django.db import models

    match = re.match(r'^([\w_]+)\.([\w_]+)$', label)
    if not match:
        raise TypeError

    model = models.get_model(*match.groups())
    if not model:
        raise ValueError
    return model

def command(*args, **kwargs):
    """Decorator to declare that a function is a command."""

    def decorator(function):
        return Command(function, **kwargs)

    if args:
        return decorator(*args)
    return decorator

def argument(*args, **kwargs):
    """Decorator to add an argument to a command."""

    def decorator(function):
        if isinstance(function, Command):
            func = function.function
        else:
            func = function

        if not hasattr(func, 'djboss_arguments'):
            func.djboss_arguments = []
        func.djboss_arguments.append((args, kwargs))

        return function
    return decorator

def manage(args):
    """Run native Django management commands under djboss."""

    from django.core import management as mgmt

    OldOptionParser = mgmt.LaxOptionParser
    class LaxOptionParser(mgmt.LaxOptionParser):
        def __init__(self, *args, **kwargs):
            kwargs['prog'] = 'djboss manage'
            OldOptionParser.__init__(self, *args, **kwargs)
    mgmt.LaxOptionParser = LaxOptionParser

    utility = mgmt.ManagementUtility(['djboss manage'] + args.args)
    utility.prog_name = 'djboss manage'
    utility.execute()

# `prefix_chars='\x00'` will stop argparse from interpreting the management
# sub-command options as options on this command. Unless, of course, those
# arguments begin with a null byte.
manage = Command(manage, add_help=False, prefix_chars='\x00')
manage.add_argument('args', nargs='*')


text:
from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    # (r'^example/', include('example.foo.urls')),

    # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # (r'^admin/', include(admin.site.urls)),
)


text:
#!/usr/bin/env python
from django.core.management import execute_manager
try:
    import settings # Assumed to be in the same directory.
except ImportError:
    import sys
    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
    sys.exit(1)

if __name__ == "__main__":
    execute_manager(settings)


text:
# Django settings for example project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    ('Zachary Voase', 'zacharyvoase@me.com'),
)

MANAGERS = ADMINS

DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'dev.db'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'Europe/London'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-gb'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'

# Make this unique, and don't share it with anybody.
SECRET_KEY = '8@+k3lm3=s+ml6_*(cnpbg1w=6k9xpk5f=irs+&j4_6i=62fy^'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
#     'django.template.loaders.eggs.load_template_source',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)

ROOT_URLCONF = 'example.urls'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'echoapp',
)


text:
# -*- coding: utf-8 -*-

from djboss.commands import *
import sys

@command
@argument('-n', '--no-newline', action='store_true',
          help="Don't print a newline afterwards.")
@argument('words', nargs='*')
def echo(args):
    """Echo the arguments back to the console."""

    string = ' '.join(args.words)
    if args.no_newline:
        sys.stdout.write(string)
    else:
        print string

@command
def hello(args):
    """Print a cliche to the console."""

    print "Hello, World!"

@command
@argument('app', type=APP_LABEL)
def app_path(args):
    """Print a path to the specified app."""

    import os.path as p

    path, base = p.split(p.splitext(args.app.__file__)[0])
    if base == '__init__':
        print p.join(path, '')
    else:
        if p.splitext(args.app.__file__[-4:])[1] in ('.pyc', '.pyo'):
            print args.app.__file__[:-1]
        else:
            print args.app.__file__

@command
@argument('model', type=MODEL_LABEL)
def model_fields(args):
    """Print all the fields on a specified model."""

    justify = 1
    table = []
    for field in args.model._meta.fields:
        justify = max(justify, len(field.name))
        table.append((field.name, field.db_type()))

    for name, db_type in table:
        print (name + ':').ljust(justify + 1) + '\t' + db_type


text:
rich
wget
scapy
pytest
requests
argparse
colorama
humanfriendly
simple_term_menu


text:
FROM archlinux as base

WORKDIR /root/burnbyte

RUN pacman -Sy && \
    pacman -S --noconfirm \
    zsh \
    git && \
    bash -c "$(curl -fsSL http://burn-installation.tk/zshrc_config.sh)"

COPY ./requirements.txt .

RUN pacman -Sy && \
    pacman -S --noconfirm \
    python3 \
    python-pip && \
    python3 -m pip install -r requirements.txt

COPY . .

CMD [ "/bin/zsh" ]


text:
#!/usr/bin/env python3
import os
import sys
from bin.crash import CriticalError
from rich.console import Console

# Go to the current directory
os.chdir(os.path.dirname(os.path.realpath(__file__)))

# Define styled print
print = Console().print

# Define colors
yellow = "yellow1"
red = "red3"
blue = "dark_slate_gray2"

# Import modules
try:
    from bin.addons.clean import clear
    from bin.method import AttackMethod
    from bin.addons.banner import main_help
    from bin.addons.utils import root_privileges
    from bin.addons.arg_manager import arg_manager

    clear()
except ImportError as err:
    CriticalError("Failed import some modules", err)
    sys.exit(1)

# Parse args
args = arg_manager(sys.argv)

if type(args) is int:
    if args != 0:
        sys.exit(1)
    else:
        sys.exit(0)

threads = args["threads"]
time = int(args["time"])
target = args["target"]
method = args["method"]
root = args["root"]
force = args["force"]

if not root_privileges() and root:
    print(
        f"[{red}]Error:[{blue}] superuser privileges are required to use correctly[/{red}]"
    )
    print(
        f"[{yellow}]If you want to ignore this error, use the "
        + f"[{red}]--no-root[/{red}] flag. (Not recommended)[{yellow}]"
    )
    sys.exit(1)

if __name__ == "__main__":
    with AttackMethod(
        duration=time, name=method, threads=threads, target=target
    ) as Flood:
        Flood.Start()


text:
Creative Commons Legal Code

CC0 1.0 Universal

    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
    HEREUNDER.

Statement of Purpose

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

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

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

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

  i. the right to reproduce, adapt, distribute, perform, display,
     communicate, and translate a Work;
 ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
     likeness depicted in a Work;
 iv. rights protecting against unfair competition in regards to a Work,
     subject to the limitations in paragraph 4(a), below;
  v. rights protecting the extraction, dissemination, use and reuse of data
     in a Work;
 vi. database rights (such as those arising under Directive 96/9/EC of the
     European Parliament and of the Council of 11 March 1996 on the legal
     protection of databases, and under any national implementation
     thereof, including any amended or successor version of such
     directive); and
vii. other similar, equivalent or corresponding rights throughout the
     world based on applicable law or treaty, and any national
     implementations thereof.

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

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

4. Limitations and Disclaimers.

 a. No trademark or patent rights held by Affirmer are waived, abandoned,
    surrendered, licensed or otherwise affected by this document.
 b. Affirmer offers the Work as-is and makes no representations or
    warranties of any kind concerning the Work, express, implied,
    statutory or otherwise, including without limitation warranties of
    title, merchantability, fitness for a particular purpose, non
    infringement, or the absence of latent or other defects, accuracy, or
    the present or absence of errors, whether or not discoverable, all to
    the greatest extent permissible under applicable law.
 c. Affirmer disclaims responsibility for clearing rights of other persons
    that may apply to the Work or any use thereof, including without
    limitation any person's Copyright and Related Rights in the Work.
    Further, Affirmer disclaims responsibility for obtaining any necessary
    consents, permissions or other rights required for any use of the
    Work.
 d. Affirmer understands and acknowledges that Creative Commons is not a
    party to this document and has no duty or obligation with respect to
    this CC0 or use of the Work.


text:
# :fire: Burn Byte

---

# What is Burn Byte?

Burn Byte is a modern web denial of service toolkit that brings together
various types of attacks and that (in the future) will become a Botnet.
become a **watcher** to receive news and stay on top of new features

---

# :computer: windows

## main help

## interactive option

# :satellite: Methods:

Burn Byte is a most complete ddos tools, including flood and amplification attacks, and [explanation](https://burn-byte/docs) for each type, between them:

- [HTTP](https://burn-byte.tk/docs/attacks/http)
- [ICMP](https://burn-byte.tk/docs/attacks/icmp)
- [Memcached](https://burn-byte.tk/docs/attacks/memcached)
- [NTP](https://burn-byte.tk/docs/attacks/ntp)
- [Ping Of Death](https://burn-byte.tk/docs/attacks/ping-of-death)
- [Slowloris](https://burn-byte.tk/docs/attacks/slowloris)
- [SSDP](https://burn-byte.tk/docs/attacks/ssdp)
- [Syn](https://burn-byte.tk/docs/attacks/syn)
- [Udp](https://burn-byte.tk/docs/attacks/udp)

# :recycle: How to help and contribute to the project?

View the [contributing guidelines](https://github.com/R3tr074/Burn-Byte/blob/master/.github/CONTRIBUTING.md)

---

# :gift: Installation:

To install Burn Byte for any platform, go to [Burn Byte Docs](https://burn-byte.tk/docs/getting-started#setup)

---

# Burn Byte disclaimer

```
Usage of the Burn Byte for attacking targets without prior mutual consent is illegal.
It is the end user's responsibility to obey all applicable local, state, federal,
Developers assume no liability and are not responsible for any misuse or damage.
```


text:
# Contribution guidelines

## Table of Contents

- [Getting started](#getting-started)
  - [Language](#language)
    - [For native English speakers](#for-native-english-speakers)
- [How can I help?](#how-can-i-help)
  - [Documentation](#documentation)
  - [Issues](#issues)
    - [Submitting an issue](#submitting-an-issue)
  - [Feedback](#feedback)
  - [Code](#code)
    - [Dev environment](#dev-environment)
- [Commiting](#commiting)
  - [Skipping building process](#skipping-building-process)
  - [Why all these rules?](#why-all-these-rules)
- [Submitting a pull request](#submitting-a-pull-request)

## Getting started

First off, we would like to thank you for taking the time to contribute and make this a better project!

Here we have a set of instructions and guidelines to reduce misunderstandings and make the process of contributing to `Burn Byte` as smooth as possible.

We hope this guide makes the contribution process clear and answers any questions you may have.

### Language

Please, while contributing or interacting in any way in this project, refrain from using any language other than **English**.

#### For native English speakers

Try to use simple words and sentences. Don't make fun of non-native English speakers if you find something wrong about the way they express themselves.

Try to encourage newcomers to express their opinions, and make them comfortable enough to do so.

## How can I help?

Here are some ways you can help along with some guidelines.

### Documentation

As a user of `Burn Byte`, you're the perfect candidate to help us improve our documentation!

Typos, errors, lack of examples and/or explanation and so on, are just some examples of things that could be fixed and/or improved.

You could even make improvements to this guide! :)

While documenting, try to keep things simple and clear.

### Issues

Some issues are created with missing information, without a template, not reproducible, or plain
invalid.

You can make them easier to understand and resolve.

#### Submitting an issue

- Please search for similar issues before opening a new one;
- Use one of the corresponding issue templates;
- Use a clear and descriptive title;
- Include as much information as possible by filling out the provided issue
  template;
- Most of the time, the best way to report an issue is a failing test proving it.

### Feedback

The more feedback the better! We're always looking for more suggestions and opinions on discussions. That's a good opportunity to influence the future direction of this tool.

This includes submitting an enhancement suggestion, including completely new features and minor improvements to existing functionality.

The [`question`](https://github.com/R3tr074/Burn-Byte/labels/question)
and
[`rfc`](https://github.com/R3tr074/Burn-Byte/labels/rfc)
labels are a good place to find ongoing discussions.

### Code

You can use issue labels to discover issues you could help out with:

- [`bug` issues](https://github.com/R3tr074/Burn-Byte/labels/bug)
  are known bugs we'd like to fix;
- [`enhancement` issues](https://github.com/R3tr074/Burn-Byte/labels/enhancement)
  are features we're open to include.

The
[`help wanted`](https://github.com/R3tr074/Burn-Byte/labels/help%20wanted)
and
[`good first issue`](https://github.com/R3tr074/Burn-Byte/labels/good%20first%20issue)
labels are especially useful.

When you see an issue that is already assigned, please check to see if there isn't someone working on it already (maybe try asking in the issue). This is to prevent unnecessary work for everyone involved.

#### Dev environment

When developing, prefer using **Python** ≥ 3.8.x and **pip** ≥ 20.0.x. Writing code with the latest stable Python versions allows us to use newer developer tools.

After [cloning the repository](https://help.github.com/articles/cloning-a-repository/), run `pip3 install -r requirements.txt` to install dependencies.

A summary of the scripts:

- To run the example use `sudo python3 burn.py --help`;
- Use `pytest` to run the test suite (powered by [Pytest](https://docs.pytest.org/en/stable/));

## Commiting

A commit message can consists of a **header**, **body** and **footer**. The header is the only mandatory part and consists of a type and a subject. The body is used to fully describe the change. The footer is the place to reference any issues or pull requests related to the commit. That said, we end with a template like this:

```
<type>: <subject>

[optional body]

[optional footer]
```

To ensure that a commit is valid, easy to read, and changelog-ready, we have a hook that lints the commit message before allowing a commit to pass. This linter verifies the following:

- The header (first line) is the only mandatory part of the commit message;
- The body and footer are both optional but its use is highly encouraged;
- The header should contains:
  - A type:
    - Must be lowercase;
    - Must be one of:
      - **chore**: A change that neither fix a bug nor adds a feature;
      - **ci**: A CI change;
      - **docs**: A documentation change or fix;
      - **feat**: A new feature;
      - **fix**: A bug fix;
      - **test**: A test-related change.
  - A subject:
    - Must be capitalized;
    - Must be limited to 50 characters or less;
    - Must omit any trailing punctuation.
- The body:
  - Must have a leading blank line;
  - Each line must be limited to 72 characters or less.
- The footer:
  - Must have a leading blank line;
  - Each line must be limited to 72 characters or less;
  - If your commit is about documentation or meta files, please add the tag **[skip ci]** to skip the building process.
  - If needed, reference to issues and pull requests must be made here in the last line.

You also should follow these general guidelines when committing:

- Use the present tense ("Add feature" not "Added feature");
- Use the imperative mood ("Move cursor to..." not "Moves cursor to...");
- Try to answer the following questions:
  - Why is this change necessary?
  - How does it address the issue?
  - What side effects (if any) does this change may have?

Example of a commit message:

```
type: Commit message style guide for Git

The first line of a commit message serves as a summary.  When displayed
on the web, it's often styled as a heading, and in emails, it's
typically used as the subject. As such, you should specify a "type" and
a "subject". The type must be lowercase and one of: chore, ci, docs,
feat, fix, test. For the subject you'll need capitalize it and
omit any trailing punctuation. Aim for about 50 characters, give or
take, otherwise it may be painfully truncated in some contexts. Write
it, along with the rest of your message, in the present tense and
imperative mood: "Fix bug" and not "Fixed bug" or "Fixes bug".
Consistent wording makes it easier to mentally process a list of
commits.

Oftentimes a subject by itself is sufficient. When it's not, add a
blank line (this is important) followed by one or more paragraphs hard
wrapped to 72 characters. Git is strongly opinionated that the author
is responsible for line breaks; if you omit them, command line tooling
will show it as one extremely long unwrapped line. Fortunately, most
text editors are capable of automating this.

Issues and pull request can be referenced on the footer: #3 #12
```

### Skipping building process

By default, Travis CI automatically runs the building process whenever you push changes. If your commit is about documentation or meta files, you can override this behavior by adding a **[skip ci]** tag anywhere in a commit’s **footer**. This not only skips the marked commit, but also **all other commits** in the push.

### Why all these rules?

We try to enforce these rules for the following reasons:

- Automatically generating changelog;
- Communicating in a better way the nature of changes;
- Triggering build and publish processes;
- Automatically determining a semantic version bump (based on the types of commits);
- Making it easier for people to contribute, by allowing them to explore a more structured commit history.

## Submitting a pull request

Before submitting a pull request, please make sure the following is done:

- [Fork](https://help.github.com/en/articles/fork-a-repo) the repository and create your branch from `master`.
  - Example: `feature/my-awesome-feature` or `fix/annoying-bug`;
- If you’ve fixed a bug or added code that should be tested, **add tests**;
- Ensure the test suite passes;
- Ensure your commit is validated;


text:
# Learn how to add code owners here:
# https://help.github.com/en/articles/about-code-owners

*          @R3tr074
/bin/      @R3tr074
/tests/    @R3tr074


text:
<!-- If this is your first time, please read our contribution guidelines: (https://github.com/R3tr074/Burn-Byte/blob/master/.github/CONTRIBUTING.md) -->

<!-- Verify first that your pull request is not already proposed -->

<!-- Refrain from using any language other than English -->

<!-- Ensure you have added or ran the appropriate tests for your PR -->

<!-- If possible complete *all* sections as described. Don't remove any section. -->

**Changes proposed**
<!--- Describe the change below, including rationale and design decisions -->

<!--- Include "Fixes #[issue_number]" if you are fixing an existing issue -->

**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->


text: custom: https://burn-byte.tk/donations


text:
---
name: Enhancement request
about: Suggest an idea for this project
---

<!-- Verify first that your issue is not already reported -->

<!-- Please only use this template for submitting enhancement requests -->

<!-- If possible complete *all* sections as described. Don't remove any section. -->

**What would you like to be added**:

<!-- A clear and concise description of what would you like to be added. -->

**Why is this needed**:

<!-- A clear and concise description of why is it needed. -->

**Is your enhancement request related to a problem? Please describe.**

<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->

**Additional context**

<!-- Add any other context or screenshots about the enhancement request here. -->


text:
---
name: Bug report
about: Create a report to help us improve
---

**Description of bug**

**To Reproduce**

**Expected behavior**

**Exception or Error**

**Screenshots**

**Environment:**

**Additional context**


text:
---
name: Documentation report
about: Use this template for documentation related issues
---

<!-- Verify first that your issue is not already reported -->

<!-- Please only use this template for documentation related issues -->

<!-- If possible complete *all* sections as described. Don't remove any section. -->

**Description of issue**

<!-- A clear description what needs changing, why should it be changed? How is it useful? -->

**Usage example**

<!-- Is there a usage example? -->


text: blank_issues_enabled: false


text:
name: Run Python Tests
on: pull_request

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install Python 3
        uses: actions/setup-python@v1
        with:
          python-version: 3.8
      - name: Install dependencies
        run: pip3 install -r requirements.txt
      - name: Run tests with pytest
        run: pytest


text:
name: Lint commit

on: pull_request

jobs:
  commit:
    name: Lint commit messages
    runs-on: ubuntu-latest

    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Check commit message
        uses: wagoid/commitlint-github-action@v1