Minify and obfuscate GLSL or HLSL code


Shader Minifier

Build status

Shader Minifier is a tool that minifies and obfuscates shader code (GLSL and HLSL). Its original use-case is for the demoscene, for optimizing 4k and 64k intros. It is also suitable for reducing the size of the shaders in other applications (e.g. webgl, games).

In the context of 4kB intros, Shader Minifier help developers maintain and iterate on human-readable files, while shipping optimized code. Even when a shader is minified by hand by experienced demosceners, Shader Minifier is often able to optimize it further. See this 2010 report.

If your application uses multiple shaders, use the --preserve-externals option. Values such as the uniforms won't be renamed, which makes it easier to use in your application (at the expense of a slightly bigger shader).


  • Parse and print the GLSL or HLSL code.
  • Generate a file (such as a C header) that can be embedded in an application.
  • Strip spaces, remove comments.
  • Remove useless parens.
  • Simplify constant expressions: 3.14159 * 2. becomes 6.28318.
  • Remove curly braces whenever possible: if(test){v.x=4; return b++;} is replaced with if(test)return v.x=4,b++;.
  • Squeeze definitions: float a=2.;float b; becomes float a=2.,b;.
  • Consistently rename vector fields (e.g. use foo.xy instead of foo.rg) to help the compression.
  • Rename variables, typically to one character.
  • Reuse the variable names as much as possible: a local variable may have the same name as a global variable not used in the function; two functions may have the same name using function overloading.
  • Analyze the context and make statistics to compute the variable name that will be the most compression-friendly.
  • Inline variables.
  • Remove unused local variables.

Example output

/* File generated with Shader Minifier 1.1.6
# define VAR_MOUSE "f"
# define VAR_RESOLUTION "y"
# define VAR_TIME "v"

const char *heart_frag =
 "uniform float v;"
 "uniform vec2 y;"
 "uniform vec4 f;"
 "void main()"
   "vec2 f=(2.*gl_FragCoord.xy-y)/y.y;"
   "float r=mod(v,2.)/2.,a=pow(r,.2)*.5+.5;"
   "float m=atan(f.x,f.y)/3.14159,x=length(f),e=abs(m),o=(13.*e-22.*e*e+10.*e*e*e)/(6.-5.*e),l=step(x,o)*pow(1.-x/o,.25);"



Download Shader Minifier here:

It is a command-line tool. Without argument, it will show the usage. If you are not on Windows, you will need mono:

$ shader_minifier.exe  # Windows
$ mono shader_minifier.exe  # Linux, Mac...
USAGE: shader_minifier.exe [--help] [-o <string>] [-v] [--hlsl] [--format <text|indented|c-variables|c-array|js|nasm>]
                           [--field-names <rgba|xyzw|stpq>] [--preserve-externals] [--preserve-all-globals]
                           [--no-inlining] [--no-renaming] [--no-renaming-list <string>] [--no-sequence] [--smoothstep]


    <filename>...         List of files to minify


    -o <string>           Set the output filename (default is shader_code.h)
    -v                    Verbose, display additional information
    --hlsl                Use HLSL (default is GLSL)
    --format <text|indented|c-variables|c-array|js|nasm>
                          Choose to format the output (use none if you want just the shader)
    --field-names <rgba|xyzw|stpq>
                          Choose the field names for vectors: 'rgba', 'xyzw', or 'stpq'
    --preserve-externals  Do not rename external values (e.g. uniform)
                          Do not rename functions and global variables
    --no-inlining         Do not automatically inline variables
    --no-renaming         Do not rename anything
    --no-renaming-list <string>
                          Comma-separated list of functions to preserve
    --no-sequence         Do not use the comma operator trick
    --smoothstep          Use IQ's smoothstep trick
    --help                display this list of options.

In short:

  • List the shaders you want to minify on the command-line.

  • Use -o to choose the output file (by default, it will use shader_code.h). If you pass - for the output, it will be printed on stdout.

  • Use --format to control the output format. By default, it will create a C header. There are other options to get only the shader, or have it in a .js or nasm file.


4kB intros

4kB intros typically use a single shader file. The default flags should work well:

shader_minifier.exe -o shader_code.h fragment.glsl

We recommend that you frequently check the output of Shader Minifier to make sure there are no obvious problems. Use inlining where possible.

If you desperately need to save a few bytes, try another value of --field-names. It can affect the size after compression.

64kB intros

The recommandation is to use:

shader_minifier.exe --format c-array --preserve-externals *.frag -o shaders.h

Then, in your C or C++ code, include the file:

const char* shaderSources[] = {
#include shaders.h

Since the uniforms are not renamed, prefer shorter names when possible. Hopefully a future version of Shader Minifier will improve this.


Use --format js. It will define a variable for each shader, the variable name being derived from the input file. We expect you to run a Javascript minifier on the output file.

Other applications

The simplest solution is to minify each file separately:

shader_minifier.exe --format text --preserve-externals file.glsl -o file_opt.glsl

The output may be used as a drop-in replacement for your original shaders.


Shader Minifier will preserve the preprocessor directives (the lines starting with #), except that it strips the spaces.

If you define a macro, Shader Minifier will notice the name of the macro and won't rename the occurrences of the macro. It also doesn't rename variables used inside the macro. Clever macros are discouraged and can break the shader.


If you want to temporary turn off the minifier, use the //[ and //] comments. This can be useful as a workaround if you get a parser error.

Variables inside the region won't be renamed. Spaces will be stripped.

void GSScene( triangleadj GSSceneIn input[6], inout TriangleStream<PSSceneIn> OutputStream )
    PSSceneIn output = (PSSceneIn)0;


Automatic inlining

Shader Minifier will try to automatically inline some variables. This happens when:

  • the variable is used only once in the current block,
  • and the variable is not used in a sub-block (e.g. inside a loop),
  • and the init value is trivial (doesn't depend on a variable).

If inlining causes a bug in your code, you can disable it with --no-inlining and please report a bug.

Explicit Inlining

Shader Minifier will always inline variables that starts with i_. Inlining can allow the Minifier to simplify the code further.

For example, this input:

bool i_debug = false;
int i_level = 5;

int foo(int x, int y) {
  if (i_debug) {

  return 2 * i_level * x;

will be simplified into:

int foo(int x,int y)
  return 10*x;

If you want to aggressively reduce the size of your shader, try inlining more variables. Inlining can have performance implications though (if the variable stored the result of a computation), so be careful with it.

Inlining can lead to repetition in the shader code, which may make the shader longer (but the output may be more compression-friendly).


At this time, do not use overloaded functions (two functions with the same name but different arguments) in the input. The output probably won't compile.

On the other hand, Shader Minifier will aggressively use function overloading in the output. If two functions have a different number of arguments, they may have the same name in the output. This reduces the number of identifiers used by the shader and make it more compression friendly.

Bugs and limitations

  • The parser is not complete. Some constructs are not yet supported.
  • Don't use overloaded functions.
  • Avoid macros that contain references to other variables.

Please give feedback in the bugtracker. If something is blocking you, you can file a bug or update an existing bug. We rely on your feedback to prioritize the work.

Slightly outdated user manual:

Contributions are welcome.

Created by Laurent Le Brun (LLB / Ctrl-Alt-Test).

  • Renaming conflict with reserved words - minified shader fails to compile

    Renaming conflict with reserved words - minified shader fails to compile

    With a high number of local variables in the shader, new renamed identifiers get up to do, which is a GLSL reserved word and the minified shader fails to compile with some Intel drivers.

    A list of reserved words not used for new identifiers would help with that.

    Here is such a list in another similar minifier project: And here are those reserved words with 3 or less letters extracted from that project:

    u        # this seems like a typo to me, but who knows :)

    Btw, thanks for this great project!

    opened by michalfapso 5
  • Add stdout as output option

    Add stdout as output option


    I was wondering if it'd be possible to add an output option to print the minified shader into stdout, which would allow piping with other tools and programs instead of handling files

    opened by Lutymane 5
  • fail: multiple returns, ifdef preprocessor branching

    fail: multiple returns, ifdef preprocessor branching

    Related: #27


    vec3 func() {
    #ifdef CONDITION
      return vec3( 1.0 );
      return vec3( 0.0 );


    vec3 v(){
    #ifdef CONDITION
    return vec3(1.);}


    vec3 v(){
    #ifdef CONDITION
    return vec3(1.);
    return vec3(0.};
    opened by 0b5vr 4
  • support template string JS output

    support template string JS output

    For a while template literals have been supported in browsers, which allows us to define multiline strings without the need for escape characters like \n.

    So a minified shader output could simply be outputted multiline, just like --format none would do, but with backticks enclosing the text. So instead of, what gets now outputted with --format js:

    var var_U_RESOLUTION = "m"
    var var_U_TIME = "v"
    var shader_frag =
     "#version 300 es\n" +
     "uniform float v;" +
     "uniform vec2 m;" +
     "const float f=3.14159,s=50.,n=.01;struct Intersection{bool intersected;vec3 position;vec3 normal;};" +
     "float e(in vec2 v)" +
     "{" +
       "return fract(sin(dot(v.xy,vec2(12.9898,78.233)))*43758.5);" +
     "}" +
     "float x(in vec2 v)" +
     "{" +
       "vec2 f=floor(v),n=fract(v);" +
       "float m=e(f),s=e(f+vec2(1.,0.)),y=e(f+vec2(0.,1.)),I=e(f+vec2(1.,1.));" +
       "vec2 p=n*n*(3.-2.*n);" +
       "float i=mix(m,s,smoothstep(0.,1.,n.x)),x=mix(y,I,smoothstep(0.,1.,n.x)),l=mix(i,x,smoothstep(0.,1.,n.y));" +
       "return l;" +
     "}" +
    // snip

    the same thing could be written via template strings:

    var var_U_RESOLUTION = "m"
    var var_U_TIME = "v"
    var shader_frag = `
    #version 300 es
    uniform float v;uniform vec2 m;const float f=3.14159,s=50.,n=.01;struct Intersection{bool intersected;vec3 position;vec3 normal;};float e(in vec2 v){return fract(sin(dot(v.xy,vec2(12.9898,78.233)))*43758.5);}float x(in vec2 v){vec2 f=floor(v),n=fract(v);float m=e(f),s=e(f+vec2(1.,0.)),y=e(f+vec2(0.,1.)),I=e(f+vec2(1.,1.));vec2 p=n*n*(3.-2.*n);float i=mix(m,s,smoothstep(0.,1.,n.x)),x=mix(y,I,smoothstep(0.,1.,n.x)),l=mix(i,x,smoothstep(0.,1.,n.y));return l;} // snip

    Template literals are supported in all mayor browsers for quite some time now. see:

    opened by nylki 3
  • Minifier strips closing #else and #endif lines if code path contains return statement.

    Minifier strips closing #else and #endif lines if code path contains return statement.

    Minifying the following produces the error:

    vec4 foobar() { 
    #if (SOME_CONSTANT == 0)
      return vec4(texture2D(someTexture, texCoord).rgb, 1.0);
      return vec4(1.0);
    void main(void) {
      gl_FragColor = foobar();

    Was able to reproduce it here too

    The minifier version 1.1 did not have this bug (however that one had another issue that causes NVIDIA drivers to not accept certain minified GLSL. Seems like it's re-using certain names for variables as well as functions.).

    opened by rafaelspring 2
  • Shader Minifier website using Bolero F#

    Shader Minifier website using Bolero F#

    Create a small website (heavily built on top of the Bolero template) that runs Shader Minifier in the browser, using WebAssembly.

    This is a prototype; it's not yet possible to change the flags for Shader Minifier.

    Try it online:

    opened by laurentlb 2
  • 0*vec3 gets optimized to 0

    0*vec3 gets optimized to 0

    The shader

    const vec3 x = 0.*vec3(1.,0.,1.);

    gets minified to const vec3 f=0.;, resulting in compiler errors. Expected behavior would be const vec3 f=vec3(0.);.

    Interestingly, glslang-validator will validate the output of shader_minifier as correct (?), which makes these kind of issues hard to debug.

    Observed on version 1.2.

    opened by LeStahL 2
  • Update the online minifier

    Update the online minifier

    • The tool needs a UX update.
    • It should be more mobile friendly.
    • It should use the latest version of Shader Minifier
    • It would be nice if it supported multiple versions of Shader Minifier.

    opened by laurentlb 2
  • Error with vector arrays (uvec3, bvec3)

    Error with vector arrays (uvec3, bvec3)

    For arrays like this:

    const uvec3[24] SWIZZLE_ROT = uvec3[24](
      uvec3(0u, 0u, 0u),

    I'm getting:

    System.Exception: Parse error:
    const uvec3[24] SWIZZLE_ROT = uvec3[24](
    Expecting: identifier
       at [email protected]433.Invoke(String message)
       at Main.minify(Tuple`2[] files)
       at[] files)

    I found that swapping the brackets to the end makes the minifier work again:

    const uvec3 SWIZZLE_ROT[24]

    But unfortunately I'm using WebGL2, which expects the brackets before the variable identifier, and not afterwards.

    opened by maierfelix 2
  • Optimize the use of 2-letter characters

    Optimize the use of 2-letter characters

    Instead of using "aa", "ab", "ac"... take into account the frequency of the characters and the context in which they are used.

    opened by laurentlb 2
  • Shader Minifier crashes and clears input file

    Shader Minifier crashes and clears input file

    This little snippet of code causes shader minifier to crash and clear the input file:

    const int TEST = 3;
    void main () {
      int[5] a = {1,2,3,4,5};
      gl_FragColor = a[TEST];

    I suspect it also took down the server(trying it in the online version) but I didn't confirm this yet due to obvious reasons.

    opened by LJ1102 2
  • Strip unused global functions and vars

    Strip unused global functions and vars

    Any chance of adding a separate option for this?


    float f(){
      float r = 1.;
      return r;
    vec2 pos = vec2(0.5);
    void main(){
      gl_FragColor = vec4(1.);

    Current output:

    float n(){return 1.;}vec2 r=vec2(.5);void main(){gl_FragColor=vec4(1.);}


    void main(){gl_FragColor=vec4(1.);}
    opened by Lutymane 1
  • Add #define logic

    Add #define logic


    The minifier doesn't consider #define/#undef and doesn't optimize #if blocks

    Example input:

    #define MUT_0
    #undef MUT_1
    float f(){
      float r = 1.;
      #ifdef MUT_0
        r = mut0(r);
      #ifdef MUT_1
        r = mut1(r);
      return r;

    1.3.1 gives:

    #define MUT_0
    #undef MUT_1
    float M(){float M=1.;
    #ifdef MUT_0
    #ifdef MUT_1
    return M;}

    So it would make sense to preserve #if blocks only if there are no corresponding #define/#undef statements and process them if they are present

    opened by Lutymane 1
  • --aggressive-inlining is not safe

    --aggressive-inlining is not safe


    float noinl9(float x) {
    	const float old = x;
    	x = 100.0;
    	return old + x;

    It currently minifies to:

    float noinl9(float x)
      return x=100.,x+x;
    opened by laurentlb 0
  • Inline variable re-assignments

    Inline variable re-assignments

    1. Even if we need the variable f, we can inline the last assignment here (since A is not used afterwards):
    return f;
    1. We could get rid of the variable here, by inlining everything:
    vec2 A=vec2(s,1.);
    return A;

    One way to detect these patterns is to introduce new variables when there's an assignment, similar to the SSA form (often seen in compilers). By introducing new variable names, detecting which ones are effectively constant, and aggressively inlining, we should be able to perform many optimizations.

    opened by laurentlb 0
  • Sort declarations by type

    Sort declarations by type

    in float a;
    in vec2 b;
    in float c;

    could be minified as:

    in float a,c;
    in vec2 b;

    Right now, we merge only adjacent declarations of the same type. It is often safe to reorder the definitions (e.g. when there's no initialization value, or when it's trivial).

    opened by laurentlb 0
  • 1.3.2(Jan 1, 2023)

    What's Changed

    Main changes include:

    • Preserve comments inside verbatim blocks by @laurentlb in
    • Inlining: inline more variables by @laurentlb in
    • Unused functions are removed by default by @eldritchconundrum in
    • Optimize conditional expressions by @laurentlb in
    • Arithmetic: better matching of int operations; disable the unsafe x*0 optimization by @laurentlb in
    • Make PI detection a bit less sensitive by @laurentlb in
    • Optimize vec constructors using swizzles by @laurentlb in
    • Skip useless vec constructors by @laurentlb in
    • Prefer ints instead of floats in the vec constructor by @laurentlb in
    • Simplify call to vec when all arguments are equal by @laurentlb in
    • Inline const values of type int,float,bool by @laurentlb in
    • Apply the sequence operator trick only when it's useful by @laurentlb in
    • Group declarations by @laurentlb in
    • Disable dead code removal if there's a preprocessor directive by @laurentlb in
    • Recursively remove unused functions by @laurentlb in

    Full Changelog:

    Source code(tar.gz)
    Source code(zip)
    shader_minifier.exe(2.28 MB)
  • 1.3.1(Nov 12, 2022)

    What's Changed

    Main changes include:

    • Support "precision" statements by @laurentlb in
    • Aggro-inlining: don't inline variables with a prefix ++ or -- operator by @laurentlb in
    • Fix stackoverflow error in simplifyExpr by @laurentlb in

    Full Changelog:

    Source code(tar.gz)
    Source code(zip)
    shader_minifier.exe(2.27 MB)
  • 1.3(Oct 23, 2022)

    What's Changed

    (some changes, e.g. documentation, cleanup, or refactoring, are not included in this list)

    • Support switch statements by @jwatzman in
    • Iterate inlining and simplification until we can do no more by @jwatzman in
    • Drop "in" qualifier from function parameters by @jwatzman in
    • Add option to aggressively inline all literals and consts by @jwatzman in
    • Add struct names to forbidden list by @jwatzman in
    • Iterate inlining and simplification only when we actually inline by @jwatzman in
    • Allow inlining one-line functions by @jwatzman in
    • Macro names: preserve the case of the original variable names by @laurentlb in
    • Fix dangling else bug by @laurentlb in
    • Swap operands of commutative operators to reduce the number of parentheses by @laurentlb in
    • Shader Minifier website using Bolero F# by @laurentlb in
    • Support array types by @laurentlb in

    New Contributors

    • @virtualzavie made their first contribution in
    • @jwatzman made their first contribution in

    Full Changelog:

    Source code(tar.gz)
    Source code(zip)
    shader_minifier.exe(2.27 MB)
  • 1.2(Jan 13, 2022)

    What's Changed

    • Make Shader Minifier twice as fast by @laurentlb in
    • Migrate option parser to Argu by @laurentlb in
    • Use template string for JS output by @laurentlb in
    • Fix parentheses when the comma operator is in a function call by @laurentlb in
    • Rewriter: remove useless braces in a few more cases by @laurentlb in
    • Parser: better support for HLSL geometry shaders by @laurentlb in
    • README: Add proper documentation by @laurentlb in
    • Rewrite the full pi constant as acos(-1.) by @eldritchconundrum in
    • Fix -0.0 by @eldritchconundrum in
    • Allow shadowing of external values by @laurentlb in
    • Optimize the use of 2-letter characters by @laurentlb in
    • Properly rename exported values in a multifile context by @laurentlb in
    • New renaming strategy for when minifying multiple files by @laurentlb in
    • New formatting output: indented text by @laurentlb in
    • Inlining: automatically inline trivial values by @laurentlb in
    • Improve float precision by @laurentlb in
    • Add option to disable auto-inlining and document it by @laurentlb in
    • Automatically remove unused local variables by @laurentlb in
    • Even better formatting of floats by @laurentlb in

    Full Changelog:

    Source code(tar.gz)
    Source code(zip)
    shader_minifier.exe(2.20 MB)
Laurent Le Brun
Author of Starlark, ex-Bazel developer, I work on IDEs and I like the demoscene.
Laurent Le Brun
HLSL Parser and Translator for HLSL, GLSL, and MSL.

HLSLParser This is a fork of Unknownworld's hlslparser adapted to our needs in The Witness. We currently use it to translate pseudo-HLSL shaders (usin

null 315 Dec 25, 2022
glslcc: Cross-compiler for GLSL shader language (GLSL->HLSL,METAL,GLES,GLSLv3)

glslcc: Cross-compiler for GLSL shader language (GLSL->HLSL,METAL,GLES,GLSLv3) @septag glslcc is a command line tool that converts GLSL code to HLSL,

Sepehr Taghdisian 435 Dec 17, 2022
⚔️ A tool for cross compiling shaders. Convert between GLSL, HLSL, Metal Shader Language, or older versions of GLSL.

A cross compiler for shader languages. Convert between SPIR-V, GLSL / GLSL ES, HLSL, Metal Shader Language, or older versions of a given language. Cross Shader wraps glslang and SPIRV-Cross, exposing a simpler interface to transpile shaders.

Alain Galvan 207 Dec 30, 2022
Shader cross compiler to translate HLSL (Shader Model 4 and 5) to GLSL

XShaderCompiler ("Cross Shader Compiler") Features Cross compiles HLSL shader code (Shader Model 4 and 5) into GLSL Simple to integrate into other pro

Lukas Hermanns 345 Dec 9, 2022
Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.

News Visual Studio 2013 is no longer supported As scheduled, Microsoft Visual Studio 2013 is no longer officially supported. Please upgrade to at leas

The Khronos Group 2.4k Jan 9, 2023
LLVM IR and optimizer for shaders, including front-end adapters for GLSL and SPIR-V and back-end adapter for GLSL

Licensing LunarGLASS is available via a three clause BSD-style open source license. Goals The primary goals of the LunarGLASS project are: Reduce the

LunarG, Inc. 153 Dec 8, 2022
HLSL to GLSL language translator based on ATI's HLSL2GLSL. Used in Unity.

HLSL to GLSL shader language translator ⚠️ As of mid-2016, the project is unlikely to have any significant developments. At Unity we are moving to a d

Aras Pranckevičius 522 Dec 18, 2022
GLSL optimizer based on Mesa's GLSL compiler. Used to be used in Unity for mobile shader optimization.

GLSL optimizer ⚠️ As of mid-2016, the project is unlikely to have any significant developments. At Unity we are moving to a different shader compilati

Aras Pranckevičius 1.6k Jan 3, 2023
Obfuscate calls to imports by patching in stubs. ICO works on both X86 and X64 binaries.

ICO adds a new section into the image, then begins building stubs for each import that uses a extremely basic routine to decrypt an RVA and places them into the section.

null 43 Dec 15, 2022
Automatically de-obfuscate ollvm and generate binaries

AntiOllvm Automatically deobfuscate binaries and generate new binaries. Chinese Help 中文帮助点击 帮助 Decriptor Software obfuscation protection is very commo

sanfengAndroid 71 Dec 6, 2022
glsl code blocks for org-mode

GLSL code blocks for Emacs Org-mode This org-mode extension adds the capability to run GLSL code blocks directly from inside Emacs and immediately dis

null 31 Dec 1, 2022
『HLSL シェーダーの魔導書』(ISBN978-4-7981-6428-1)のサンプルファイル

# サンプルデータについて 本データは、『HLSL シェーダーの魔導書』(清原 隆行 著、翔泳社 刊)の付属データです。 なお、本データは以下のサイトから入手可能です。 - Github:

SEBook 翔泳社の本 102 Dec 15, 2022
A Visual Studio extension that provides enhanced support for editing High Level Shading Language (HLSL) files

HLSL Tools for Visual Studio This extension is for Visual Studio 2017 / 2019. Go here for the Visual Studio Code extension. HLSL Tools is a Visual Stu

Tim Jones 433 Dec 27, 2022
ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages

ShaderConductor ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages. Features Converts HLSL to readable, usable and

Microsoft 1.5k Dec 29, 2022
this is my simple voxel engine, appart from librairies like glad it is entierly written in C++ and GLSL

simple-voxel-raycaster this is my simple voxel engine, appart from librairies like glad it is entierly written in C++ and GLSL here is a gif: https://

null 2 Sep 26, 2022
VSIX Project that provides GLSL language integration.

GLSL language integration (for VS2017, 2019 and 2022) Download this extension from Visual Studio Marketplace version VS2017 & 2019 or VS 2022 preview

Daniel Scherzer 208 Dec 24, 2022
Simple printf functionality for GLSL.

Simple printf functionality for GLSL. This library is a simple proof of concept of using printf directly from a shader. The main point of being able

null 206 Dec 20, 2022
An efficient texture-free GLSL procedural noise library

Wombat An efficient texture-free GLSL procedural noise library Source: Derived from:

Brian Sharpe 200 Dec 18, 2022
Fast glsl deNoise spatial filter, with circular gaussian kernel, full configurable

glslSmartDeNoise Fast glsl spatial deNoise filter, with circular gaussian kernel and smart/flexible/adaptable -> full configurable: Standard Deviation

Michele Morrone 212 Dec 24, 2022