{"id":18631755,"url":"https://github.com/esotericpig/psychgus","last_synced_at":"2025-04-11T07:30:40.383Z","repository":{"id":50712953,"uuid":"115842671","full_name":"esotericpig/psychgus","owner":"esotericpig","description":":necktie::blue_car::nose: Easily style YAML files using Psych, like Sequence/Mapping Flow style.","archived":false,"fork":false,"pushed_at":"2022-08-01T02:08:37.000Z","size":171,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-04-25T17:41:26.616Z","etag":null,"topics":["libyaml","psych","psych-parser","psychgus","ruby","style","yaml","yaml-parser"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esotericpig.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-31T04:30:50.000Z","updated_at":"2023-08-20T01:33:41.000Z","dependencies_parsed_at":"2022-09-13T17:51:36.948Z","dependency_job_id":null,"html_url":"https://github.com/esotericpig/psychgus","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esotericpig%2Fpsychgus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esotericpig%2Fpsychgus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esotericpig%2Fpsychgus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esotericpig%2Fpsychgus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esotericpig","download_url":"https://codeload.github.com/esotericpig/psychgus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223362248,"owners_count":17133066,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["libyaml","psych","psych-parser","psychgus","ruby","style","yaml","yaml-parser"],"created_at":"2024-11-07T05:08:31.368Z","updated_at":"2024-11-07T05:08:32.903Z","avatar_url":"https://github.com/esotericpig.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Psychgus\n\n[![Gem Version](https://badge.fury.io/rb/psychgus.svg)](https://badge.fury.io/rb/psychgus)\n[![CI Status](https://github.com/esotericpig/psychgus/actions/workflows/ci.yml/badge.svg)](https://github.com/esotericpig/psychgus/actions/workflows/ci.yml)\n[![Doc Coverage](http://inch-ci.org/github/esotericpig/psychgus.svg?branch=master)](https://inch-ci.org/github/esotericpig/psychgus)\n\n[![Documentation](https://img.shields.io/badge/doc-yard-%23A0522D.svg)](https://esotericpig.github.io/docs/psychgus/yardoc/index.html)\n[![Source Code](https://img.shields.io/badge/source-github-%23211F1F.svg)](https://github.com/esotericpig/psychgus)\n[![Changelog](https://img.shields.io/badge/changelog-md-%23A0522D.svg)](CHANGELOG.md)\n[![License](https://img.shields.io/github/license/esotericpig/psychgus.svg)](LICENSE.txt)\n\nPsychgus uses the core standard library [Psych](https://github.com/ruby/psych) for working with [YAML](https://yaml.org) and extends it so that developers can easily style the YAML according to their needs.\n\nTurn this YAML...\n\n```YAML\n---\nPsych Gus:\n  Aliases:\n  - Longbranch Pennywhistle\n  - Squirts Macintosh\n  - Clementine Woolysocks\n  - Lavender Gooms\n  - Big Baby Burton\n  - Chocolate Einstein\n  - MC Clap Yo Handz\n  Skills:\n  - The Blueberry\n  - The Super Sniffer\n  - Positive Work Attitude\n```\n\nInto this:\n\n```YAML\n---\nPsych Gus:\n  Aliases: [Longbranch Pennywhistle, Squirts Macintosh, Clementine Woolysocks, Lavender\n      Gooms, Big Baby Burton, Chocolate Einstein, MC Clap Yo Handz]\n  Skills: [The Blueberry, The Super Sniffer, Positive Work Attitude]\n```\n\nThank you to the people that work hard on the Psych project.\n\nThe Psychgus name comes from the well-styled character Gus from the TV show Psych.\n\n## Contents\n\n- [Setup](#setup)\n- [Using](#using)\n    - [Simple Example](#simple-example)\n    - [Hash Example](#hash-example)\n    - [Class Example](#class-example)\n    - [Advanced Usage](#advanced-usage)\n    - [Common Stylers](#common-stylers)\n        - [Stylers Example](#stylers-example)\n- [Hacking](#hacking)\n    - [Testing](#testing)\n    - [Generating Doc](#generating-doc)\n- [License](#license)\n\n## Setup\n\nPick your poison...\n\nWith the RubyGems CLI package manager:\n\n`$ gem install psychgus`\n\nIn your *Gemspec* (*\u0026lt;project\u0026gt;.gemspec*):\n\n```Ruby\n# Pick one...\nspec.add_dependency 'psychgus', '~\u003e X.X.X'\nspec.add_development_dependency 'psychgus', '~\u003e X.X.X'\n```\n\nIn your *Gemfile*:\n\n```Ruby\n# Pick one...\ngem 'psychgus', '~\u003e X.X.X'\ngem 'psychgus', '~\u003e X.X.X', :group =\u003e :development\ngem 'psychgus', :git =\u003e 'https://github.com/esotericpig/psychgus.git', :tag =\u003e 'vX.X.X'\n```\n\nManually:\n\n```\n$ git clone 'https://github.com/esotericpig/psychgus.git'\n$ cd psychgus\n$ bundle install\n$ bundle exec rake install:local\n```\n\n## Using\n\nDocumentation (YARDoc) is available on my [GitHub Page](https://esotericpig.github.io/docs/psychgus/yardoc/index.html) and on [RubyDoc.info](https://www.rubydoc.info/gems/psychgus).\n\nTo begin styling, create a class and mix in (include) `Psychgus::Styler`. Then pass it in as a keyword arg (`stylers: MyStyler.new` or `stylers: [MyStyler1.new,MyStyler2.new]`) into one of the Psychgus methods.\n\nFor classes, you can optionally include `Psychgus::Blueberry` and return the styler(s) for the class by defining the `psychgus_stylers(sniffer)` method.\n\nInstead of making your own styler, you can also use one of the [pre-defined stylers](#common-stylers).\n\n### Contents | Using\n\n[Simple Example](#simple-example)\n| [Hash Example](#hash-example)\n| [Class Example](#class-example)\n| [Advanced Usage](#advanced-usage)\n| [Common Stylers](#common-stylers)\n\n### Simple Example\n\n```Ruby\nrequire 'psychgus'\n\nclass CoffeeStyler\n  include Psychgus::Styler\n\n  def style_sequence(sniffer,node)\n    node.style = Psychgus::SEQUENCE_FLOW\n  end\nend\n\ncoffee = {\n  'Roast'=\u003e['Light', 'Medium', 'Dark', 'Extra Dark'],\n  'Style'=\u003e['Cappuccino', 'Espresso', 'Latte', 'Mocha']\n}\n\nputs coffee.to_yaml(stylers: CoffeeStyler.new)\n\n# Output:\n# ---\n# Roast: [Light, Medium, Dark, Extra Dark]\n# Style: [Cappuccino, Espresso, Latte, Mocha]\n\nclass Coffee\n  include Psychgus::Blueberry\n\n  def initialize\n    @roast = ['Light', 'Medium', 'Dark', 'Extra Dark']\n    @style = ['Cappuccino', 'Espresso', 'Latte', 'Mocha']\n  end\n\n  def psychgus_stylers(sniffer)\n    CoffeeStyler.new\n  end\nend\n\nputs Coffee.new.to_yaml\n\n# Output:\n# --- !ruby/object:Coffee\n# roast: [Light, Medium, Dark, Extra Dark]\n# style: [Cappuccino, Espresso, Latte, Mocha]\n```\n\n### Hash Example\n\n```Ruby\nrequire 'psychgus'\n\nclass BurgerStyler\n  include Psychgus::Styler # Mix in methods needed for styling\n\n  # Style maps (Psych::Nodes::Mapping)\n  # - Hashes (key/value pairs)\n  # - Example: \"Burgers: Classic {}\"\n  def style_mapping(sniffer,node)\n    node.style = Psychgus::MAPPING_FLOW if sniffer.level \u003e= 4\n  end\n\n  # Style scalars (Psych::Nodes::Scalar)\n  # - Any text (non-alias)\n  def style_scalar(sniffer,node)\n    # Remove colon (change symbols into strings)\n    node.value = node.value.sub(':','')\n\n    # Capitalize each word\n    node.value = node.value.split(' ').map do |v|\n      if v.casecmp('BBQ') == 0\n        v.upcase()\n      else\n        v.capitalize()\n      end\n    end.join(' ')\n\n    # Change lettuce to spinach\n    node.value = 'Spinach' if node.value == 'Lettuce'\n  end\n\n  # Style sequences (Psych::Nodes::Sequence)\n  # - Arrays\n  # - Example: \"[Lettuce, Onions, Pickles, Tomatoes]\"\n  def style_sequence(sniffer,node)\n    node.style = Psychgus::SEQUENCE_FLOW if sniffer.level \u003e= 4\n  end\nend\n\nburgers = {\n  :burgers =\u003e {\n    :classic =\u003e {:sauce  =\u003e %w(Ketchup Mustard),\n                 :cheese =\u003e 'American',\n                 :bun    =\u003e 'Sesame Seed'},\n    :bbq     =\u003e {:sauce  =\u003e 'Honey BBQ',\n                 :cheese =\u003e 'Cheddar',\n                 :bun    =\u003e 'Kaiser'},\n    :fancy   =\u003e {:sauce  =\u003e 'Spicy Wasabi',\n                 :cheese =\u003e 'Smoked Gouda',\n                 :bun    =\u003e 'Hawaiian'}\n  },\n  :toppings =\u003e [\n    'Mushrooms',\n    %w(Lettuce Onions Pickles Tomatoes),\n    [%w(Ketchup Mustard), %w(Salt Pepper)]\n  ]\n}\nburgers[:favorite] = burgers[:burgers][:bbq] # Alias\n\nputs burgers.to_yaml(indent: 3,stylers: BurgerStyler.new)\n\n# Output:\n# ---\n# Burgers:\n#    Classic: {Sauce: [Ketchup, Mustard], Cheese: American, Bun: Sesame Seed}\n#    BBQ: \u00261 {Sauce: Honey BBQ, Cheese: Cheddar, Bun: Kaiser}\n#    Fancy: {Sauce: Spicy Wasabi, Cheese: Smoked Gouda, Bun: Hawaiian}\n# Toppings:\n# - Mushrooms\n# - [Spinach, Onions, Pickles, Tomatoes]\n# - [[Ketchup, Mustard], [Salt, Pepper]]\n# Favorite: *1\n\n# Or pass in a Hash. Can also dereference aliases.\nputs burgers.to_yaml({:indent =\u003e 3,:stylers =\u003e BurgerStyler.new,:deref_aliases =\u003e true})\n\n# Output:\n# ---\n# Burgers:\n#    Classic: {Sauce: [Ketchup, Mustard], Cheese: American, Bun: Sesame Seed}\n#    BBQ: {Sauce: Honey BBQ, Cheese: Cheddar, Bun: Kaiser}\n#    Fancy: {Sauce: Spicy Wasabi, Cheese: Smoked Gouda, Bun: Hawaiian}\n# Toppings:\n# - Mushrooms\n# - [Spinach, Onions, Pickles, Tomatoes]\n# - [[Ketchup, Mustard], [Salt, Pepper]]\n# Favorite:\n#    Sauce: Honey BBQ\n#    Cheese: Cheddar\n#    Bun: Kaiser\n```\n\n### Class Example\n\n```Ruby\nrequire 'psychgus'\n\nclass BurgerStyler\n  include Psychgus::Styler # Mix in methods needed for styling\n\n  def initialize(sniffer)\n    @class_level    = sniffer.level\n    @class_position = sniffer.position\n  end\n\n  # Style all nodes (Psych::Nodes::Node)\n  def style(sniffer,node)\n    # Remove \"!ruby/object:...\" for Burger classes (not Burgers class)\n    node.tag = nil if node.node_of?(:mapping,:scalar,:sequence)\n\n    # This is another way to do the above\n    #node.tag = nil if node.respond_to?(:tag=)\n  end\n\n  # Style maps (Psych::Nodes::Mapping)\n  # - Hashes (key/value pairs)\n  # - Example: \"Burgers: Classic {}\"\n  def style_mapping(sniffer,node)\n    parent = sniffer.parent\n\n    if !parent.nil?()\n      # BBQ\n      node.style = Psychgus::MAPPING_FLOW if parent.node_of?(:scalar) \u0026\u0026\n                                             parent.value.casecmp('BBQ') == 0\n    end\n  end\n\n  # Style scalars (Psych::Nodes::Scalar)\n  # - Any text (non-alias)\n  def style_scalar(sniffer,node)\n    parent = sniffer.parent\n\n    # Single quote scalars that are not keys to a map\n    # - \"child_key?\" is the same as \"child_type == :key\"\n    node.style = Psychgus::SCALAR_SINGLE_QUOTED unless parent.child_key?()\n  end\n\n  # Style sequences (Psych::Nodes::Sequence)\n  # - Arrays\n  # - Example: \"[Lettuce, Onions, Pickles, Tomatoes]\"\n  def style_sequence(sniffer,node)\n    relative_level = (sniffer.level - @class_level) + 1\n\n    # \"[Ketchup, Mustard]\"\n    node.style = Psychgus::SEQUENCE_FLOW if relative_level == 3\n  end\nend\n\nclass Burger\n  include Psychgus::Blueberry # Mix in methods needed to be stylable\n\n  attr_accessor :bun\n  attr_accessor :cheese\n  attr_accessor :sauce\n\n  def initialize(sauce,cheese,bun)\n    @bun    = bun\n    @cheese = cheese\n    @sauce  = sauce\n  end\n\n  # Return our styler(s)\n  # - Can be an Array: [MyStyler1.new, MyStyler2.new]\n  def psychgus_stylers(sniffer)\n    return BurgerStyler.new(sniffer)\n  end\n\n  # You can still use Psych's encode_with(), no problem\n  def encode_with(coder)\n    coder['Bun']    = @bun\n    coder['Cheese'] = @cheese\n    coder['Sauce']  = @sauce\n  end\nend\n\nclass Burgers\n  attr_accessor :burgers\n  attr_accessor :toppings\n  attr_accessor :favorite\n\n  def initialize()\n    @burgers = {\n      'Classic' =\u003e Burger.new(['Ketchup','Mustard'],'American'    ,'Sesame Seed'),\n      'BBQ'     =\u003e Burger.new('Honey BBQ'          ,'Cheddar'     ,'Kaiser'),\n      'Fancy'   =\u003e Burger.new('Spicy Wasabi'       ,'Smoked Gouda','Hawaiian')\n    }\n\n    @toppings = [\n      'Mushrooms',\n      %w(Lettuce Onions Pickles Tomatoes),\n      [%w(Ketchup Mustard),%w(Salt Pepper)]\n    ]\n\n    @favorite = @burgers['BBQ'] # Alias\n  end\n\n  # You can still use Psych's encode_with(), no problem\n  def encode_with(coder)\n    coder['Burgers']  = @burgers\n    coder['Toppings'] = @toppings\n    coder['Favorite'] = @favorite\n  end\nend\n\nburgers = Burgers.new\n\nputs burgers.to_yaml(indent: 3)\n\n# Output:\n# --- !ruby/object:Burgers\n# Burgers:\n#    Classic:\n#       Bun: 'Sesame Seed'\n#       Cheese: 'American'\n#       Sauce: ['Ketchup', 'Mustard']\n#    BBQ: \u00261 {Bun: 'Kaiser', Cheese: 'Cheddar', Sauce: 'Honey BBQ'}\n#    Fancy:\n#       Bun: 'Hawaiian'\n#       Cheese: 'Smoked Gouda'\n#       Sauce: 'Spicy Wasabi'\n# Toppings:\n# - Mushrooms\n# -  - Lettuce\n#    - Onions\n#    - Pickles\n#    - Tomatoes\n# -  -  - Ketchup\n#       - Mustard\n#    -  - Salt\n#       - Pepper\n# Favorite: *1\n\n# Or pass in a Hash. Can also dereference aliases.\nputs burgers.to_yaml({:indent =\u003e 3,:deref_aliases =\u003e true})\n\n# Output:\n# --- !ruby/object:Burgers\n# Burgers:\n#    Classic:\n#       Bun: 'Sesame Seed'\n#       Cheese: 'American'\n#       Sauce: ['Ketchup', 'Mustard']\n#    BBQ: {Bun: 'Kaiser', Cheese: 'Cheddar', Sauce: 'Honey BBQ'}\n#    Fancy:\n#       Bun: 'Hawaiian'\n#       Cheese: 'Smoked Gouda'\n#       Sauce: 'Spicy Wasabi'\n# Toppings:\n# - Mushrooms\n# -  - Lettuce\n#    - Onions\n#    - Pickles\n#    - Tomatoes\n# -  -  - Ketchup\n#       - Mustard\n#    -  - Salt\n#       - Pepper\n# Favorite:\n#    Bun: 'Kaiser'\n#    Cheese: 'Cheddar'\n#    Sauce: 'Honey BBQ'\n```\n\n### Advanced Usage\n\n```Ruby\nrequire 'psychgus'\n\nclass MyStyler\n  include Psychgus::Styler\n\n  def style_sequence(sniffer,node)\n    node.style = Psychgus::SEQUENCE_FLOW\n  end\nend\n\ncoffee = {\n  'Coffee' =\u003e {\n    'Roast'=\u003e['Light', 'Medium', 'Dark', 'Extra Dark'],\n    'Style'=\u003e['Cappuccino', 'Espresso', 'Latte', 'Mocha']\n  }\n}\neggs = {\n  'Eggs' =\u003e {\n    'Color'=\u003e['Brown', 'White', 'Blue', 'Olive'],\n    'Style'=\u003e['Fried', 'Scrambled', 'Omelette', 'Poached']\n  }\n}\n\nfilename = 'coffee-and-eggs.yaml'\nstyler = MyStyler.new\noptions = {:indentation=\u003e3, :stylers=\u003estyler, :deref_aliases=\u003etrue}\n\ncoffee_yaml = coffee.to_yaml(options)\ncoffee_and_eggs_yaml = Psychgus.dump_stream(coffee,eggs,options)\n\n\n# High-level emitting\nputs Psychgus.dump(coffee,options)\nputs\n\nPsychgus.dump_file(filename,coffee,eggs,options)\nputs File.readlines(filename)\nputs\n\nputs Psychgus.dump_stream(coffee,eggs,options)\nputs\n\nputs coffee.to_yaml(options)\nputs\n\n# High-level parsing\n# - Because to_ruby() will be called, just use Psych:\n#   - load(), load_file(), load_stream(), safe_load()\n\n# Mid-level emitting\nstream = Psychgus.parse_stream(coffee_and_eggs_yaml,options)\n\nputs stream.to_yaml()\nputs\n\n# Mid-level parsing\nputs Psychgus.parse(coffee_yaml,options).to_ruby\nputs\n\nputs Psychgus.parse_file(filename,options).to_ruby\nputs\n\ni = 0\nPsychgus.parse_stream(coffee_and_eggs_yaml,options) do |doc|\n  puts \"Doc ##{i += 1}:\"\n  puts \"  #{doc.to_ruby}\"\nend\nputs\n\n# Low-level emitting\ntree_builder = Psychgus::StyledTreeBuilder.new(styler,options)\nvisitor = Psych::Visitors::YAMLTree.create(options,tree_builder)\n\nvisitor \u003c\u003c coffee\nvisitor \u003c\u003c eggs\n\nputs visitor.tree.to_yaml\nputs\n\n# Low-level parsing\nparser = Psychgus.parser(options)\n\nparser.parse(coffee_yaml)\n\nputs parser.handler.root.to_ruby\nputs\n```\n\n### Common Stylers\n\nA collection of commonly-used [Stylers](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers.html) and [Stylables](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylables.html) are included with Psychgus.\n\n| Styler | Description |\n| --- | --- |\n| [CapStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/CapStyler.html) | Capitalizer for Scalars |\n| [FlowStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/FlowStyler.html) | FLOW style changer for Mappings \u0026 Sequences |\n| [MapFlowStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/MapFlowStyler.html) | FLOW style changer for Mappings only |\n| [NoSymStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/NoSymStyler.html) | Symbol remover for Scalars |\n| [NoTagStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/NoTagStyler.html) | Tag remover for classes |\n| [SeqFlowStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/SeqFlowStyler.html) | FLOW style changer for Sequences only |\n\n#### Stylers Example\n\n```Ruby\nrequire 'psychgus'\n\nclass EggCarton\n  def initialize\n    @eggs = {\n      :styles =\u003e ['fried', 'scrambled', ['BBQ', 'ketchup \u0026 mustard']],\n      :colors =\u003e ['brown', 'white', ['blue', 'green']]\n    }\n  end\nend\n\nputs EggCarton.new.to_yaml(stylers: [\n  Psychgus::NoSymStyler.new,\n  Psychgus::NoTagStyler.new,\n  Psychgus::CapStyler.new,\n  Psychgus::FlowStyler.new(4)\n])\n\n# Output:\n# ---\n# Eggs:\n#   Styles: [Fried, Scrambled, [BBQ, Ketchup \u0026 Mustard]]\n#   Colors: [Brown, White, [Blue, Green]]\n\nputs EggCarton.new.to_yaml\n\n# Output (without Stylers):\n# --- !ruby/object:EggCarton\n# eggs:\n#   :styles:\n#   - fried\n#   - scrambled\n#   - - BBQ\n#     - ketchup \u0026 mustard\n#   :colors:\n#   - brown\n#   - white\n#   - - blue\n#     - green\n```\n\n## Hacking\n\n```\n$ git clone 'https://github.com/esotericpig/psychgus.git'\n$ cd psychgus\n$ bundle install\n$ bundle exec rake -T\n```\n\n### Testing\n\nRun tests:\n\n`$ bundle exec rake test`\n\n### Generating Doc\n\nGenerate doc:\n\n`$ bundle exec rake doc`\n\nClean \u0026amp; generate pristine doc:\n\n`$ bundle exec rake clobber doc`\n\n## License\n\n[GNU LGPL v3+](LICENSE.txt)\n\n\u003e Psychgus (\u003chttps://github.com/esotericpig/psychgus\u003e)  \n\u003e Copyright (c) 2017-2024 Bradley Whited  \n\u003e \n\u003e Psychgus is free software: you can redistribute it and/or modify  \n\u003e it under the terms of the GNU Lesser General Public License as published by  \n\u003e the Free Software Foundation, either version 3 of the License, or  \n\u003e (at your option) any later version.  \n\u003e \n\u003e Psychgus is distributed in the hope that it will be useful,  \n\u003e but WITHOUT ANY WARRANTY; without even the implied warranty of  \n\u003e MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  \n\u003e GNU Lesser General Public License for more details.  \n\u003e \n\u003e You should have received a copy of the GNU Lesser General Public License  \n\u003e along with Psychgus.  If not, see \u003chttp://www.gnu.org/licenses/\u003e.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesotericpig%2Fpsychgus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesotericpig%2Fpsychgus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesotericpig%2Fpsychgus/lists"}